什么是单个命名空间导致不卫生的宏? (在LISP中)

时间:2010-08-15 12:49:54

标签: macros clojure lisp scheme hygiene

有人声称LISP中的单个命名空间会导致不卫生的宏。 http://community.schemewiki.org/?hygiene-versus-gensym

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

具有导致宏观卫生的单个,双重或多个名称空间究竟是什么?

1 个答案:

答案 0 :(得分:7)

Lisp-2意味着你有两个命名空间:一个用于函数,一个用于其他东西。

这意味着您不太可能在宏中重新绑定宏中的函数值(或var值)。

在Lisp-1中,由于有一个命名空间,因此(统计上,但实际上不是)命中现有定义的可能性是其两倍。

实际上,Lisp-1的卫生覆盖了诸如gensym和Scheme的令人困惑的广泛syntax-structure之类的东西 - 就像保持卫生一样的宏。

我可以说,问题主要是一个稻草人的论点:它只是较贫穷或较旧的实施中的问题。

Clojure通过gensym或读者宏myvar#提供卫生宏(#基本上是gensym)。

你不必担心本地范围在你的宏中重新绑定你的函数:Clojure都是干净的:

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)

这里有一些可变的卫生:

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"

请注意我们性感的gensym'd x#