Что это за единое пространство имен, которое приводит к негигиеническим макросам?(в ЛИСП) - PullRequest
8 голосов
/ 15 августа 2010

Некоторые утверждают, что одно пространство имен в LISP приводит к негигиеничным макросам. http://community.schemewiki.org/?hygiene-versus-gensym

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

Что именно в наличии одного, двух или нескольких пространств имен приводит к макро-гигиене?

1 Ответ

7 голосов
/ 16 августа 2010

Lisp-2 означает, что у вас есть два пространства имен: одно для функций, другое для другого.

Это означает, что у вас меньше шансов перепривязать значение функции (или значение var) в макросе, невольно.

В Lisp-1, поскольку есть одно пространство имен, вероятность того, что вы достигнете (статистически, но не практически), в существующем определении, в два раза выше.

На самом деле, Lisp-1 имеет гигиеническое покрытие, такое как gensym, и невероятно широкий набор схем, подобных syntax-structure, в Scheme, которые обеспечивают гигиеничность.

Насколько я могу судить, проблема в основном является аргументом соломенного чучела: это проблема только в более плохих или старых реализациях.

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#.

...