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

Re: hygiene when using multiple instances of a macro..?



On Tue, 9 Aug 2005, Panu A. Kalliokoski wrote:

On Mon, Aug 08, 2005 at 10:55:51AM -0400, Andre van Tonder wrote:

  (define-syntax (can-we-stand-duplicates a-macro)
    (quasisyntax
     (if ',a-macro                     ; note quote
         (let ((x 3)) (,a-macro #f))
         x)))

I don't understand why the quote is needed, though; and it seems I was
not the only one...

Without the quote, one would get the expansion (I have kept the LETs for readability)

  (if can-we-stand-duplicates
      (let ((x#1 3))
         (if #f
             (let ((x#2 3)) (#f #f))
             x))
      x)

but can-we-stand-duplicates is a macro, not a runtime value, and is therefore unbound in the above expression (to an extent this can be regarded as an implementation-dependent detail, since one could legitimately also have expected t to be bound to a transformer even at runtime).


Ah, so it's the _expansion_ that creates the new colour for the
(quasi)syntax form.  Great.


Well almost :) Each evaluation of (quasi)syntax, even if they occur during the same macro expansion step, creates a new colour, so

  (bound-identifier=? (syntax x) (syntax x))  ;==> #f


Another point that crossed my mind was the difference between

(lambda (form) (quasisyntax (,(cadr form) 'foo 'bar)))
and
(lambda (form) (quasisyntax ,((cadr form) 'foo 'bar)))

when (cadr form) is a macro; that is, does it make any difference
whether the macro is left for the expander for further expansion or
called directly, reentrantly?


Only the first example will work. In the second example, you are attempting to apply (cadr form) to arguments 'foo and 'bar. Since (cadr form) evaluates to a piece of syntax, not a procedure, this will fail.

Cheers
Andre