Hygienic macros (was: do...until wisdom needed...)

Hannah Schroeter hannah at schlund.de
Mon Apr 23 11:57:15 EDT 2001


Hello!

In article <lcitk1iwxd.fsf at gaffa.mit.edu>,
Douglas Alan  <nessus at mit.edu> wrote:
>hannah at schlund.de (Hannah Schroeter) writes:

>[...]

>> And you can fix this in Lisp too, using gensyms (uniquely generated
>> symbols for the purpose of macro expansion), like this:

>Indeed.  It's just that many people (yours truly included) find having
>to resort to gensym to be ugly and tedious.

>From a theoretical POV, that's true. But so much tedious, it isn't.

Usually, if you write more macros, you use things like (from CLOCC):

(defmacro with-gensyms (syms &body body)
  "Bind symbols to gensyms.  First sym is a string - `gensym' prefix.
Inspired by Paul Graham, <On Lisp>, p. 145."
  `(let (,@(mapcar (lambda (sy) `(,sy (gensym ,(car syms)))) (cdr syms)))
    , at body))

or

(defmacro with-gensyms (syms &body body)
  "Create gensyms, useful for creating macros."   ; LMH
  `(let ,(mapcar #'(lambda (s)
                     `(,s (gensym)))
                 syms)
     , at body))

Then, you write things like 

(defmacro numerical-if (expr pos zero neg)
 (with-gensyms (expr-value)
  `(let ((,expr-value ,expr))
     (cond ((plusp ,expr-value) ,pos)
           ((zerop ,expr-value) ,zero)
           (t ,neg)))))

>[...]

>namespace. Hygiene should be the rule, however, rather than the
>exception.

>From a theoretical POV, yes, true. From a practical POV, I don't
find Lisp's macro facility *too* tedious. However, you could devise
some things like

(defmacro define-hygienical-macro ...)

which uses some symbol syntax to discriminate whether a symbol
should be one gensym'ed once for the whole macro expansion per name,
or it should occur as is in the expansion. An usage example could
be:

(define-hmacro numerical-if (expr pos zero neg)
 `(let ((?expr-value ,expr))
    (cond ((plusp ?expr-value) ,pos)
          ((zerop ?expr-value) ,zero)
          (t ,neg))))

In that case, the '?' would be the "to be gensym'ed" marker.

Kind regards,

Hannah.



More information about the Python-list mailing list