Open gelisam opened 1 year ago
The above is a missing feature in quasiquote
, but I have now also encountered a bug in quasiquote
:
-- should result in '(1 2 `(3 ,'4)), instead results in '(1 2 `(3 4))
(example
`(1 2 `(3 ,'4)))
Why wouldn't `,'4 be 4?
`,'4
should indeed result in '4
, but under a nested quasiquote,
``,'4
should result in
`,'4
At least, that's the behaviour in Racket:
$ racket
Welcome to Racket v7.4.
> `,'4
4
> ``,'4
'`,'4
See the "A quasiquote form within the original datum increments the level of quasiquotation" section of Racket's quasiquote documentation.
I think Racket's behaviour makes a lot of sense. It allows macros to splice-in unknown expressions inside a quasiquote without having to worry about whether the unknown expression itself contain a quasiquote. For example, suppose a macro verbose
wraps its input inside a quasiquote:
(verbose (+ 2 2))
=>
`(the expression (+ 2 2) equals ,(+ 2 2))
=>
'(the expression (+ 2 2) equals 4)
then consider what happens when verbose
is given an input which contains a quasiquote:
(verbose `(two plus two is ,(+ 2 2)))
=>
`(the expression `(two plus two is ,(+ 2 2)) equals ,`(two plus two is ,(+ 2 2)))
=>
?
with Racket's behaviour, the result is the one I expect:
`(the expression `(two plus two is ,(+ 2 2)) equals ,`(two plus two is ,(+ 2 2)))
=>
`(the expression `(two plus two is ,(+ 2 2)) equals (two plus two is 4))
whereas with the alternative behaviour, I get a different result:
`(the expression `(two plus two is ,(+ 2 2)) equals ,`(two plus two is ,(+ 2 2)))
=>
`(the expression `(two plus two is 4) equals (two plus two is 4))
I encountered exactly that problem: I was very confused as to why
(define-syntax-rule (example-macro-syntax action)
(group
(define-macro (my-macro)
(do (stx <- action)
(pure `(quote ,stx))))
(example (my-macro))))
was complaining that stx
was not in scope, and it turned that the problem was that define-syntax-rule
is implemented in a similar way to verbose
, so its quasiquote
is trying to evaluate ,stx
much earlier than I expected.
I much prefer to use quasiquote than
close-syntax
, but I often have to useclose-syntax
to append a(List Syntax)
at the end of alist-contents
. Being able to writeinstead of
would improve a lot of code.
In terms of implementation, this requires adding a new syntactic sugar, so that
,@
desugars tounquote-splicing
, and to tweak thequasiquote.kl
implementation to give it the right semantics.