一些人聲稱LISP中的單個命名空間會導致不衛生的宏。 http://community.schemewiki.org/?hygiene-versus-gensym導致不衛生宏的單個命名空間是什麼? (在LISP中)
http://www.nhplace.com/kent/Papers/Technical-Issues.html
什麼恰恰是它關於有單,雙或多個命名空間,導致宏觀衛生?
一些人聲稱LISP中的單個命名空間會導致不衛生的宏。 http://community.schemewiki.org/?hygiene-versus-gensym導致不衛生宏的單個命名空間是什麼? (在LISP中)
http://www.nhplace.com/kent/Papers/Technical-Issues.html
什麼恰恰是它關於有單,雙或多個命名空間,導致宏觀衛生?
Lisp-2意味着你有兩個命名空間:一個用於功能,一個用於其他的東西。
這意味着你不太可能在不知不覺中重新綁定宏中的函數值(或var值)。
在Lisp-1中,由於存在一個命名空間,因此您(在統計上但不是實際上)命中現有定義的概率是其兩倍。
實際上,Lisp-1s的衛生已經涵蓋了像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#
。
其實'rev'宏的工作原理主要是因爲Clojure如何自動解析由文法中引入的符號 - 引用形式,以及名稱空間限定符號可能未命名('reverse'實際上變成擴展中的'clojure.core/reverse';'(let [reverse:foo](rev ...))'不是問題,因爲'rev'表單的擴展從不提及'反向「 - 它提到'clojure.core/reverse')。就我所知,這是Clojure對宏觀衛生辯論的一項創新貢獻。 – 2010-08-16 00:26:49
當然'gensym'在這裏是非常重要的,但是一個包裝系統(包裝是CL lingo;這就是Clojure土地使用的「名稱空間」這個詞)對於非衛生的宏觀健康也是至關重要的,而Clojure的自動解決方法是這是一種特別聰明的方式,儘可能地幫助它。 – 2010-08-16 00:29:12
我完全忘了語法引用完全解決了它所包含的符號:謝謝你!我想我的回答是正確的,但這是一個重要/有趣的事情要注意。我在這個問題的答案的早期迭代中實際上利用了這一點:http://stackoverflow.com/questions/3480377/clojure-namespace-management-is-there-a-way-to-save-and-restore -cl-of-state-of-cl 再次感謝米哈爾爲清理事情。 – Isaac 2010-08-16 00:51:07
由於您在三個小時以後沒有收到任何(真實)答案:您可以嘗試在「Lambda the Ultimate」上提問。你可能會被踢出去,因爲這個列表實際上是關於編程語言的研究,但那裏的人肯定能回答你的問題。 http://lambda-the-ultimate.org/ – Eike 2010-08-15 16:40:22