*[Slate reference manual section 2.6.2 on quoting and unquoting](http://slate.tunes.org/doc/progman/node12.html#SECTION00046200000000000000)
*Common Lisp backquote implementation, written in Common Lisp. (public
domain) Author: Guy L. Steele Jr. Date: 27 December 1985. To be used with
2010 patch by Alex Plotnick regarding the simplification pass.
* Common Lisp backquote implementation, written in Common Lisp. (public domain)
Author: Guy L. Steele Jr. Date: 27 December 1985. To be used with 2010 patch
by Alex Plotnick regarding the simplification pass.
* SBCL backquote implementation (derived from CMUCL, used the October 2010
version).
@@ -135,50 +135,48 @@ Known Issues
marker inside the expression being quasiquoted. Such expressions may lead to
confusion between the body of expressions being quasiquoted and the internal
quasiquote infrastructure. If you use these kinds of tricks, you're on your
own. In `fare-quasiquote`, the syntax markers are the `quasiquote`,
`unquote`, `unquote-splicing` and `unquote-nsplicing` symbols present in the
`fare-quasiquote` package and not exported. Any objects that would be used
as markers instead of these interned symbols would lead to the same "bug" if
somehow used inside quasiquoted expressions; at least, non-interned symbols
or gensyms would allow to avoid this bug in expressions being `read`. The
own. In `fare-quasiquote`, the syntax markers are the `quasiquote`,`unquote`,
`unquote-splicing` and `unquote-nsplicing` symbols present in the
`fare-quasiquote` package and not exported. Any objects that would be used as
markers instead of these interned symbols would lead to the same "bug" if
somehow used inside quasiquoted expressions; at least, non-interned symbols or
gensyms would allow to avoid this bug in expressions being `read`. The
"perfect" solution would be to use objects `gensym`ed at the moment a given
`quasiquote` is read, and kept in a lexical variable to prevent
introspective cheat by `#.` syntax. Then, after simplifying expressions, we
could pass the read expression through functions that would `subst`itute
proper symbols for the markers, from the `fare-quasiquote` package if
pretty-printing is to be supported, or otherwise from the CL package. Note
that this would have to be interleaved with support for working inside
vectors and other syntax. This is all very tricky and until further notice
is left as an exercise to the intrepid reader. Thus, while the behaviour of
our implementation isn't strictly correct, we don't go through the hassle of
modifying it into something much less readable just for the sake of
preventing code that would deliberately confuse the quasiquote engine. Now,
if we imagine that some code were dynamically generated based on system
introspection, that could contain some of our magic markers, then this code
would have to be made safe for interaction with `quasiquote`; this might (or
might not?) require making `quasiquote` 100% fool-proof.
`quasiquote` is read, and kept in a lexical variable to prevent introspective
cheat by `#.` syntax. Then, after simplifying expressions, we could pass the
read expression through functions that would `subst`itute proper symbols for
the markers, from the `fare-quasiquote` package if pretty-printing is to be
supported, or otherwise from the CL package. Note that this would have to be
interleaved with support for working inside vectors and other syntax. This is
all very tricky and until further notice is left as an exercise to the
intrepid reader. Thus, while the behaviour of our implementation isn't
strictly correct, we don't go through the hassle of modifying it into
something much less readable just for the sake of preventing code that would
deliberately confuse the quasiquote engine. Now, if we imagine that some code
were dynamically generated based on system introspection, that could contain
some of our magic markers, then this code would have to be made safe for
interaction with `quasiquote`; this might (or might not?) require making
`quasiquote` 100% fool-proof.
* This implementation allows for simplifying quasiquoting of literals and other
self-evaluating objects into the object itself, instead of a `` `(quote
,object)`` expression, if you enable the `#+quasiquote-passes-literals` feature.
This is the behaviour of the simplifier in CMUCL and SBCL, but some people
have expressed concerns that it might not be strictly allowed in letter or
spirit by the Common Lisp standards, and it can make the pretty-printer
trickier.
self-evaluating objects into the object itself, instead of a `` `(quote ,object)``
expression, if you enable the `#+quasiquote-passes-literals` feature. This is
the behaviour of the simplifier in CMUCL and SBCL, but some people have
expressed concerns that it might not be strictly allowed in letter or spirit
by the Common Lisp standards, and it can make the pretty-printer trickier.
* This version works inside simple vectors, so as to support unquoting inside
the `#(...)` syntax as the standard mandates. To do that, it replaces the
hash-left-paren reader-macro as well as the backquote reader-macro. Note
that this does not work in `#1A(...)` syntax. This phenomenon has been
documented before in the [following message](http://groups.google.com/groups?q=author:kaz%40ashi.footprints.net&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=cf333042.0303141409.bbf02e9%40posting.google.com&rnum=4).
hash-left-paren reader-macro as well as the backquote reader-macro. Note that
this does not work in `#1A(...)` syntax. This phenomenon has been documented
before in the [following message](http://groups.google.com/groups?q=author:kaz%40ashi.footprints.net&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=cf333042.0303141409.bbf02e9%40posting.google.com&rnum=4).
* Interestingly, I haven't seen the following problem stated, to know which is
correct of `` `#5(1 ,@'(2 3))``. In other words, does the read argument to ` #()`
mean something at read-time or at vector-creation-time? Of course, in the
correct of `` `#5(1 ,@'(2 3))``. In other words, does the read argument to `
#()` mean something at read-time or at vector-creation-time? Of course, in the
original intended usage, outside of any quasiquoting, read-time and
vector-creation-time are one and the same. But what when quasiquote breaks
up that identity? Our answer is that it means something at
vector-creation-time.
vector-creation-time are one and the same. But what when quasiquote breaks up
that identity? Our answer is that it means something at vector-creation-time.
* The CLHS section 2.4.6 says that `(x1 x2 ... xn . atom)` is same as `(append
[x1] [x2] [x3] ... [xn] (quote atom))` --- mind that the atom is preserved.
@@ -242,7 +240,7 @@ constructors is read.
The principle of the MUP is that:
* structure readers that don't want to support unquote MUST be wrapped into
something that dynamically binds `*quasiquote-level*` to `0`.
something that dynamically binds `*quasiquote-level*` to 0.
* structure readers `#c(args)` that do want to support unquote MUST accumulate
formal arguments to a structure constructor into a list `args`, then, if