What is it about a single namespace that leads to unhygienic macros? (in LISP)

1.1k views Asked by At

Some claim that a single namespace in LISP leads to unhygienic macros. http://community.schemewiki.org/?hygiene-versus-gensym

http://www.nhplace.com/kent/Papers/Technical-Issues.html

What precisely is it about having single, dual or multiple namespaces that leads to macro hygiene?

1

There are 1 answers

4
Isaac On BEST ANSWER

Lisp-2 means you have two namespaces: one for functions, one for the other stuff.

This means you're less likely to rebind a function value (or var value) in a macro, unwittingly.

In Lisp-1, since there's one namespace, you're (statistically, but not practically) twice as likely to hit an existing definition.

In reality, Lisp-1s have hygiene covered with things like gensym and Scheme's confusingly wide array of syntax-structure-like macros that keep things hygienic.

As best I can tell, the issue is mostly a straw-man argument: it's only an issue in the poorer or older implementations.

Clojure offers hygienic macros through gensym or the reader macro myvar# (the # is essentially gensym).

And you don't have to worry about local scope rebinding your function in your macros, either: Clojure is all clean:

user=> (defmacro rev [xs] `(reverse ~xs))
#'user/rev
user=> (rev [1 2 3])
(3 2 1)
user=> (let [reverse sort] (rev [1 2 5 3 6]))
(6 3 5 2 1)

And here's some variable hygiene:

user=> (defmacro k [] (let [x# "n"] x#))
#'user/k
user=> (k)
"n"
user=> (let [x "l"] (k))
"n"
user=> (let [x "l"] (str (k) x))
"nl"

Notice our sexy gensym'd x#.