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

Hannah Schroeter hannah at schlund.de
Wed Apr 18 11:26:44 EDT 2001


Hello!

In article <lcitk358fr.fsf at gaffa.mit.edu>,
Douglas Alan  <nessus at mit.edu> wrote:
>[...]

>The problem with non-hygienic macros is that variable names used by the
>macro implementation can conflict with variable names that are passed
>into the macro.  Hygienic macros solve this problem by putting the
>variables in different namespaces.

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

(defmacro list2 (&rest elements)
 (let ((variable-names (mapcar #'(lambda (foo) (gensym)) elements)))
  `(let
    ,(mapcar #'(lambda (vname form) `(,vname ,form)) variable-names elements)
    (list ,@(loop for i in variable-names collect i collect i)))))

(this doesn't really make much sense in reality, as you can just
write a function
(declaim (inline list2))
(defun list2 (&rest elements)
 (loop for i in elements collect i collect i))
but is to illustrate the avoiding of name capturing in Lisp macros).

An advantage of that is that you *can* capture names if you intend
to, such as in Lisp's loop macro, which locally defines a "loop-finish"-
macro to abort the loop from inside. Something that can't be done IIRC
with Schemes "hygienic macros".

Kind regards,

Hannah.

PS: The gensym thing is often made easier with macros like with-gensyms
in Lisp, so to write hygienic macros in Lisp isn't really much more difficult
than in Scheme, and you can in fact program an emulation of Schemes
define-syntax with CL's macro facility.



More information about the Python-list mailing list