Reputation: 10910
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.
Upvotes: 1
Views: 248
Reputation: 1113
[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 quasiquote
d 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)
Upvotes: 0
Reputation: 6502
(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)
Upvotes: 2
Reputation: 66371
According to R5RS,
Unpredictable behavior can result if any of the symbols
quasiquote
,unquote
, orunquote-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.
Upvotes: 1