[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Elementary question about backquote in T.

    Date: 23 Oct 85 21:59:49 PDT (Wed)
    From: Sanjai Narain <narain@rand-unix.ARPA>
    If we define:

	    (define-macro (bar x) `(list ,(car x)))

    then (macro-expand '(bar '(1 2)) *scratch-env*) ==> (list quote). That is, an
    attempt to evaluate (bar '(1 2)) will give an error to the effect that
    quote is unbound.

    This appears to me rather confusing. A macro is ideally a rewrite rule.
    So I expect (bar '(1 2)) to be rewritten to the form (list u) where
    u = (car '(1 2)) i.e. (list u) must be rewritten to (list 1).

No, u = (car ''(1 2)).

    This expectation is supported by the following observations:

	   >  (set x '(1 2))
	      ;; x is bound to '(1 2)

No, x is bound to (1 2).  The car of this is then 1.

	   > `(list ,(car x))

	      ==> (list 1)

    What am I missing? By the way, Franzlisp backquote behaves similarly.

    Thanks for any comments.

    -- Sanjai

For absolute precision, in the following remarks I will use
double-quotes as metasyntactic quote marks, rather than as string

In the macro call "(bar '(1 2))" the macro parameter "x" is bound to an
unevaluated argument, so the value of "x" is "'(1 2)", which is the same
as "(quote (1 2))".  When you write ",(car x)" within the backquote, it
means to take the car of the macro-expand-time value of "x".  The value
of "x" is "(quote (1 2))", so the car of that is "quote".

The resdult of expanding "(bar (1 2))" (without a single quote) would be
"(list 1)", which wpould then evaluate to "(1)".

One could also define "bar" as

	    (define-macro (bar x) `(list (car ,x)))

with the comma in a different place, so as to make the "car" operation
take place at evaluation time (run time) rather than expansion time
(compile time).  Then the macro call "(bar '(1 2))" would expand to
"(list (car '(1 2)))" which would in turn also evaluate to "(1)".