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