1

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.

Flux
  • 9,805
  • 5
  • 46
  • 92

3 Answers3

2

(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)
Sorawee Porncharoenwase
  • 6,305
  • 1
  • 14
  • 28
1

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.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • The first is a printing artefact; look at its `car`, `cadr`, and `caddr`. I don't have time to investigate the other question for you. – molbdnilo Jan 19 '21 at 19:00
0

[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)
Metaxal
  • 1,083
  • 8
  • 10
  • Okay, turns out the backtick just needs to be preceded with an antislash `\`` in SO markdown – Metaxal Jan 21 '21 at 14:46
  • 1
    Please read my answer to [How do I escape a backtick ` within in-line code in Markdown?](https://meta.stackexchange.com/a/347313/405102) – Flux Jan 21 '21 at 16:23