Behavior of "unquote" when used as the second to last symbol in a quasiquoted proper list - scheme

I am trying to produce the list (1 unquote 2) using quasiquote. I have tried this:
`(1 unquote 2)
However, in Racket, MIT Scheme and Chez Scheme, I get a dotted list: '(1 . 2).
So I tried this:
`(1 'unquote 2)
However, I get (1 'unquote 2).
I finally got the list I wanted using this technique:
`(1 unquote 2 ,((lambda (x) x) 'unquote) 2) ; Returns: '(1 unquote 2)
Why do I get a dotted list out of a quasiquoted proper list when unquote is the second to last element in the quasiquoted list?
Actually, it does not always produce a dotted list. For example:
`(1 unquote (list 2 3 4)) ; Returns: '(1 2 3 4)
Please explain this strange behavior of unquote when it is the second to last element in a quasiquoted list.

(a b c) is a shorthand for (a . (b . (c . ()))).
So (quasiquote (1 unquote 2)) is really (quasiquote (1 . (unquote 2))) which is '(1 . 2).
(Or if you want to fully expand it, (quasiquote (1 unquote 2)) is (quasiquote . ((1 . (unquote . (2 . ()))) . ())))
Similarly, (quasiquote (1 unquote (list 2 3 4))) is really (quasiquote (1 . (unquote (list 2 3 4)))) = (quasiquote (1 . (2 3 4))) = '(1 2 3 4).
By the way, an easier way to produce '(1 unquote 2) using quasiquote is:
`(1 ,'unquote 2)

According to R5RS,
Unpredictable behavior can result if any of the symbols quasiquote,
unquote, or unquote-splicing appear in positions within a <qq
template> otherwise than as described above.
And your positions are not "as described above" - the form must be (unquote expression ...).
It has been upgraded to a syntax violation in R6RS.

[writing an answer rather than a comment because it's impossible to format backticks properly in a comment. Lisp/Scheme still handles this better than markdown ;-) ]
As others have explained (esp. Sorawee), unquote (aka ,) is a special name that is treated specially when inside an quasiquoted list (aka the backtick). To prevent its special meaning, a simple workaround is to make sure the special name doesn't appear textually.
Note that unquote does not have a special meaning inside quote (by contrast to inside quasiquote).
Thus this will work in all variants of Scheme:
(define unquote-sym 'unquote) ; `unquote` is inside `quote`, so it's a mere symbol here
`(1 ,unquote-sym 2) ; '(1 unquote 2)

Related

in scheme what is the meaning of dot not on cons? why sometimes it is valid and sometime not

what is the meaning of dot, other than just cons notation?
dot as I know is just cons notation. so I don't understand the meaning here:
why:
> (equal? . 8)
Exception: invalid syntax (equal? . 8)
Type (debug) to enter the debugger.
but:
> (equal? . ((quote . ((a . (b . (c . ()))))) . ('(a b c))))
#t
what is the meaning of the dot here?
The syntax gets parsed and for a Scheme reader '(1 . (2 . ())) gets parsed and creates the same structure as '(1 2). Basically proper lists are singly linked lists where the last cdr points to the empty list.
(somefun . (5)) is the same as (somefun 5) for the reader. When the source code is turned in to a data structure, the interpreter won't know if you wrote the one or the other. Hovever (somefun . 5) doesn't get parsed to a function with one argument since the argument list itself is a number. the parser parsed it into a data structure, but your scheme implementation responsible to compile it or interpret it failed. You may use dotted list in data and some syntax like lambda for rest arguments, but it is very limited. Most of the time using dotted pairs in code fails.
A Scheme system will display structure only one way. eg. if you put in '(1 . (2 . ())) you will se (1 2) back since a dot with a list or empty list cdr gets special list visualization. If you do '(1 . (2 . 3)) it can start using the special rule since the cdr is a pair, but the next won't fly ending it up as (1 2 . 3). If you evaluate '(equal? . ((quote . ((a . (b . (c . ()))))) . ('(a b c)))) you get (equal? '(a b c) '(a b c)) back and that is because it is the simplest visualization of that structure. As code they read to the same structure and evaluate the same.
The most common problem when learning Scheme is to understand the list structure. Eg. how to create ((1 2) (3 4)) using cons and how to access the 4. If you knew it is really ((1 . (2 . ()) . ((3 . (4 . ())))) you see the 4 is after fllowing the cdr, car, cdr, then car or the simplified (cadadr '((1 2) (3 4))). The visualizer will just omit the dot and the extra set of parentheses in the cdr if it has them. eg. '((a) . (b)) will become ((a) b)

Why does '(1 2 3) evaluate to a list en Lisp (Scheme)?

The quote (') is used to introduce a pre-evaluated value, so (quote x) results in the symbol x and not what the symbol evalutes to.
Numbers, Booleans, characters and strings are self-evaluating in Scheme, so quoting them doesn't matter.
But why does (quote (1 2 3)) or (quote ()) answers #t to the predicate list?.
Should't the result be a "pre-evaluated" value? But in this case (1 2 3) has actually been evaluated to (list 1 2 3)?
Thank you.
pre-evaluated value
I'm not sure where you got that term from. I've never used it. It's not "pre-evaluated", it's unevaluated.
This is really all works from the fact Lisp (and Scheme) is Homoiconic: the structure of the program really uses lists and atoms underneath.
quote is the dual to eval: (eval (list '+ '1 '2 '3)) (and since a quoted number is just the number, (eval (list '+ 1 2 3)) does it as well) is the opposite of (quote '(+ 1 2 3)).
An evaluated list is a call, so an unevaluated call is a list.
Should't the result be a "pre-evaluated" value? But in this case (1 2 3) has actually been evaluated to (list? 1 2 3)?
You're missing some parentheses here! You get (list? '(1 2 3)) (or (list? (quote (1 2 3)). That is, (list? (list 1 2 3)). Which is true.
You can check the opposite with (eval (list '+ 1 2 3)): you get 6.
Note: Some values just evaluate to themselves (like numbers or functions. You can throw eval at it as many times as you want, and it won't change a thing: (eval (eval (eval 1))) is just 1.)
(quote (+ 1 2 3)) = '(+ 1 2 3) = (list '+ '1 '2 '3) = (list '+ 1 2 3) (numbers are self-evaluating, i.e. evaluating to self).
(eval '(+ 1 2 3)) = (+ 1 2 3) = 6. And (eval '(1 2 3)) = (1 2 3) = error.
The first identity is just syntactical. The central identity here is the second one, '(+ 1 2 3) = (list '+ '1 '2 '3). It holds because everything is evaluated in Lisp, but before that, it must be read. Which means, converted from textual source code to actual data structures.
Since ( ... ) parentheses denote lists, reading ( ... ) forms creates lists. Then, evaluating the quoted form just returns that form as is (i.e. non-evaluated). The token + gets read as a symbol +; the literals 1, 2, 3 get read as numbers 1, 2, 3. So the end result is the same as the result of evaluating the form (list '+ '1 '2 '3).
And of course all this still applies without the + inside, as well.
The quote introduces an unevaluated value, not pre-evaluated, whatever that means.
When the expression (quote X) is treated as a form to be evaluated, it simply evaluates to X itself. X is not treated as a form to be evaluated to a value, but rather the resulting value is the syntax X itself.
Quote is a way of the program expressing, "I want to use a piece of my own syntax as a value". And that's precisely what a "literal" is in computer science: a piece of program text reflected back into the program as a run-time value.
In Lisp, atoms other than symbols denote themselves when evaluated. The syntax 3 evaluates to the integer 3. They are the same thing: Lisp syntax is a data structure, and in that data structure, an integer literal 3 is already represented by the object that it denotes.
Thus, under evaluation, there is no difference between (quote 3) and just 3. "Give me the syntax 3 itself" and "give me the value of the syntax 3" are the same: just 3.
Under (quote (1 2 3)), the syntax being quoted is (1 2 3). That syntax is the list object that it looks like; quote just regurgitates it. If were to evaluate the (1 2 3) form, it would be an error: it looks like 1 is being used as an operator or function, with arguments 2 and 3. When quote is itself evaluated, it suppresses this evaluation and just yields the (1 2 3) as-is.
Because the (1 2 3) is a piece of the program syntax, however, there is a restriction in the language that this list may not be modified. An operation like (inc (car (quote (1 2 3)))) which tries to change the list to (2 2 3) invokes undefined behavior. Essentially, the program is trying to modify its own syntax; if for a moment we disregard the additional complexity that Lisp is a compiled language, this is de facto self-modifying code.

What does '(list 1 2) means in Scheme?

I'm studying SICP and at the beginning of section 2.2.2 it gives the following code: (cons '(list 1 2) (list 3 4))) and says it constructs a list like ((1 2) 3 4). But when I typed it into DrRacket(I'm using Racket here actually) it produces '((list 1 2) 3 4) and if I write (cons (list 1 2) (list 3 4)) then it'll be alright. I know in Scheme '(1 2) is equal to (list 1 2) but what does '(list 1 2) mean?
It should mean "a list consisting of the atom list, the atom 1, and the atom 2". Until Scheme evaluates the list (which the single quote prevents), it doesn't treat "list" differently from any other string.
Scheme has a convenient syntax for representing data literals: prefix any expression with ' (single quote) and the expression, rather than being evaluated, will be returned as data
For more informations:
http://courses.cs.washington.edu/courses/cse341/04wi/lectures/14-scheme-quote.html
Fix output style
First off, When you use the #!racket language in DrRacket, the default way of printing is not printing it's representation but an expression that evaluates to the same. You can turn it off from the menu language >> choose language. You select Show details and under Output style you select write
After pressing Run, when evaluating 'test you will get the output test.
Typo in expression
In section 2.2.2 there is an expression (cons (list 1 2) (list 3 4)). It is not the same as what you wrote in the question, (cons '(list 1 2) (list 3 4)). While an expression (list 1 2) applies the procedure list with values 1 and 2 and thus becomes (1 2), the expression '(list 1 2) just return the quoted data (list 1 2) unchanged.
Thus:
(cons (list 1 2) (list 3 4)) ; ==> ((1 2) 3 4)
(cons '(list 1 2) (list 3 4)) ; ==> ((list 1 2) 3 4)
'(cons '(list 1 2) (list 3 4)) ; ==> (cons '(list 1 2) (list 3 4))
The notation 'foo makes a symbol named foo.
The notation '(foo bar) makes a list with two symbols named foo and bar.
In the same way '(list foo bar) makes a list of three symbols. The symbol 'list happens to be called list.
Now (list 'foo 'bar) makes a list of two symbols called foo and bar.

Cons in scheme explanation

(cons 1 2) gives us (1 . 2).
(cons 3 4) gives us (3 . 4).
So why does (cons (cons 1 2) (cons 3 4)) give us ((1 . 2) 3 . 4)?
Why isn't it ((1 . 2) (3 . 4))?
Well, it wouldn't be ((1 . 2) (3 . 4)) because that would be a list containing two elements, each a cons pair. I'm guessing what you meant was: why isn't it ((1 . 2) . (3 . 4))?
Well, actually the following two expressions are equivalent:
'((1 . 2) . (3 . 4))
'((1 . 2) 3 . 4)
This has to do with how Scheme's dotted notation works in tandem with its representation of proper lists. Remember that this:
'(1 . (2 . (3 . (4 . ()))))
...would simply be printed as this:
(1 2 3 4)
However, this:
'(1 . (2 . (3 . 4)))
...would be printed like this:
(1 2 3 . 4)
Note that Scheme tries to use the simplified list notation as long as it can—it only falls back to explicitly dotting things once it reaches a pair which doesn't have a pair or the empty list as its cdr element.
Therefore, in your original example, the second element of that cons pair is a pair, so Scheme uses the list notation. That lets it drop the second set of parentheses and the extra dot, yielding the result you encountered.

Understanding symbols in Scheme

I am having a hard time understanding symbols in Scheme. The following confuses me:
1 ]=> (symbol? 'x)
; Value: #t
1 ]=> (symbol? '('x))
; Value: #f
I thought I understood why the first one is a symbol, but then why is '('x)) not? Can someone please explain why?
For what it's worth, I am running MIT/GNU Scheme.
In scheme '... is a shorthand for (quote ...).
Thus 'x is shorthand for (quote x).
And '(1 2 3) is shorthand (quote (1 2 3)).
When a quote expression is evaluated, the quoted values is not evaluated as an expression, but simply returned.
In (quote x) what is quoted is the symbol x. So (quote x) evaluates to the symbol x.
In (quote (1 2 3)) the quoted value is a list. It evaluates to (1 2 3).
In your slightly more complicated example, you have
'('x) which is shorthand for (quote ((quote x))).
This evaluates to the list ((quote x)). Which in most Schemes are
printed as ('x).
'('x) is a list, not a symbol. Symbols in Scheme are alphanumeric, like variables and keywords. So 'a is a symbol, and so is 'supercalafragalistic, but '(1 2 3) is a list of numbers.
I'm not sure exactly what's throwing you off, but it's probably the '. ' can be used to make symbols, but also to make lists, and other things too. Not everything that starts with ' is a symbol.

Resources