Subject: Re: Unquote
From: rpw3@rpw3.org (Rob Warnock)
Date: Mon, 06 Jun 2005 22:40:23 -0500
Newsgroups: comp.lang.lisp,comp.lang.scheme
Message-ID: <7oSdnTfHGqi6ijjfRVn-iw@speakeasy.net>
Sebastian Stern <sebastianstern@wanadoo.nl> wrote:
+---------------
| "Comma is invalid if used other than inside the body of a backquote
| expression as described above." [Common Lisp HyperSpec, 2.4.7, Comma]
| Why is this?
...
| Should it not be possible (and better, in the sense that it eliminates the
| above restriction) to have an UNQUOTE special operator?  (The comma would
| then just be its abbreviating macro character). The operation of the
| UNQUOTE special operator would be the same of that of the oridinary
| UNQUOTE, except that it would also be allowed that an UNQUOTE appears
| outside a corresponding backquote/quasiquote.
+---------------

Personally, I agree that it would be "better" in a certain sense, in
that it would permit user macros to use what Scheme calls QUASIQUOTE,
UNQUOTE, and UNQUOTE-SPLICING (backquote, command, and comma-at, resp.)
for doing their own template re-writing [and the CLHS certainly *permits*
this, see Section 2.4.6.1 "Notes about Backquote", but does not require it].
A great example of this is the Scheme Shell <http://www.scsh.net/>, which
allows one to write things like this:

    (let ((foo "filename"))	; RUN is a Scsh macro that does what
      (run (ls -l ,foo)))	;  might be called "implicit quasiquoting".

    (run (cc ,file ,@flags))	; Compile FILE with FLAGS.

Unfortunately those are illegal to a standard CL reader, as you have noted,
so in a (hypothetical) "CLsh" the above would have to look like this:

    (let ((foo "filename"))
      (run `(ls -l ,foo)))	; Note explicit backquote

    (run `(cc ,file ,@flags))	; (ditto)

+---------------
| Why does CL have the requirement that an unquote may only appear
| in a backquote?
+---------------

When this topic came up before, most of the old dogs said it was because
there were so many different existing implementations of quasiquotation
out there already -- some doing it all in the reader, some rewriting
into idiosyncratic special forms, some doing a mixture of the two,
and some even doing pretty agressive optimization of how the resulting
s-expr got constructed at runtime (or even compile time!) -- that the
best the CL committee could come up with was the set of "as if" rules
that you now see in CLHS 2.4.6 "Backquote":

    An implementation is free to interpret a backquoted form F1 as any
    form F2 that, when evaluated, will produce a result that is the same
    under EQUAL as the result implied by the above definition, provided
    that the side-effect behavior of the substitute form F2 is also
    consistent with the description given above.

Note the various possible legal renderings of this:

    `((,a b) ,c ,@d)

which are given following the above quote. It would be very difficult
(if not impossible) for a "CLsh" to figure out in any portable way
[and in some cases, even within a single implemetation] just what
the user had originally typed. That is, given this "CLsh" call:

    (run `((,a b) ,c ,@d))

the argument to the RUN macro might be any of the forms listed.

Remember, it is the *reader* doing the rewriting in CL, so the
RUN macro never sees the original form at all.


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607