
Question about a macro-defining macro
but with only a single comma before the reference to g-field i get
the
Quote:
> message that variable g-field has no value (during runtime) and with
> two commas i get that the variable #:G2415 has no value.
> Anyone who can illuminate me? I have meditated over chapter 16 of
> Grahams "On Lisp", but could not figure out how to solve this.
I have started working on an advanced tutorial on backquotes that
should turn anyone into a seasoned expert.
Nested backquotes with multiple commas are simple to understand, once
you form the right mental model. However, you have to keep in mind
that a convenient mental model that explains how the backquote works
does not necessarily correspond to how the backquote is actually
implemented.
One way to understand it like this:
1. when a backquote form is evaluated, then all of the commas which
belong to that form evaluate their adjoint expressions at that time
and these are inserted into the list.
2. Any inner backquotes and commas enclosed in them remain for a
further evaluation round.
But in reality, this isn't necessarily how it happens; it may be that
an entire backquote form and all inner backquotes are expanded into
list-constructing code in one step. To make matters more confusing,
it's possible for the expander to produce more than one representation
of the backquote: an expanded version containing the code, and another
version for pretty-printing, so that when you print the object, it
appears as nice nested backquote rather than the corresponding hairy
code.
The consequence of rule 2 is that if you have two commas in a row,
then two evaluations happen (one for each round of evaluation of the
backquote form). For instance if you have ``(,,x), the first
evaluation *conceptually* produces the non-nested backquote object
`(,<value-of-form 'x>). The leftmost comma goes with the inner
backquote and so it stays. Now if you evaluate that again, you finally
get the equivalent of (list <value-of-form <value-of-form 'x>>). (I
don't want to say (eval 'x); the <value-of-form 'x> notation indicates
evaluation, but not necessarily with EVAL). The ``natural'' evaluation
of a backquote can see lexical variables, whereas EVAL does not).
If you have N nesting levels of backquote (with N being 1 for a single
backquote) then the first evaluation round will evaluate the
*rightmost* commas in those expressions that have N commas---in other
words, those expressions that have the maximum number of commas
possible, matching the number of levels. Given `````,,,,,(+ 2 2) the
first evaluation will ``cancel'' the outermost backquote with the
rightmost comma, causing the (+ 2 2) expression to be reduced to 4,
and four backquotes and commas to remain, as if the form ````,,,,4
were produced.
But if there are fewer commas than backquotes, then none of those
commas belong to the outer backquote, and so they are not touched by
evaluation. No cancelation takes place. Thus the evaluation of
`````,,,,(+ 2 2) conceptually just strips one backquote level away,
leaving ````,,,,(+ 2 2). The (+ 2 2) is not reduced. But it will be if
another evaluation is applied, because now there are four commas
against four backquotes, so cancelation can take place.
Suppose you have this: ``,,(list '+ 2 2) . The first evaluation will
conceptually reduce to `,(+ 2 2). And then the next one finally to 4.
Two commas, two evaluations. Now suppose that you did not want this to
happen; you want the list (+ 2 2) to ``survive'' through the second
evaluation round. What do you do? You apply the trick Tim Bradshaw
showed you; you insert a quote to cancel the second evaluation:
``,',(list '+ 2 2). So the first evaluation reduces to this: `,'(+ 2
2) or equivalently `,(quote (+ 2 2)). And the next evaluation will
then cancel the backquote and comma, evaluate the (quote ...) and
leave you with (+ 2 2). This is exactly what is often needed in
macro-defining-macros; you want some form that is input into the macro
to survive into the second-level macro without undergoing an
additional evaluation.