LISPの単一の名前空間が非衛生的なマクロにつながると主張する人もいます。 http://community.schemewiki.org/?hygiene-versus-gensym
http://www.nhplace.com/kent/Papers/Technical-Issues.html
マクロの衛生状態につながる単一、二重、または複数の名前空間を持つことについて、正確には何ですか?
LISPの単一の名前空間が非衛生的なマクロにつながると主張する人もいます。 http://community.schemewiki.org/?hygiene-versus-gensym
http://www.nhplace.com/kent/Papers/Technical-Issues.html
マクロの衛生状態につながる単一、二重、または複数の名前空間を持つことについて、正確には何ですか?
Lisp-2は、2つの名前空間があることを意味します。1つは関数用、もう1つは他のもの用です。
これは、無意識のうちにマクロ内の関数値(または変数値)を再バインドする可能性が低いことを意味します。
Lisp-1では、名前空間が1つあるため、(統計的には、しかし実際にはそうではありませんが)既存の定義にヒットする可能性が2倍になります。
実際には、Lisp-1は、Schemeのようなもので覆われた衛生状態を持っており、物事を衛生的に保つ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#
。