определить синоним для макроса Clojure - PullRequest
12 голосов
/ 23 августа 2009

Итак, следуя макросу Clojure для создания синонима для функции , я обнаружил, что def не может использоваться для определения синонима для макроса. Ниже приведены примеры, которые я пробовал, что Clojure не позволяет.

;(def def-function defn)
;(def case cond)
;(def function fn)

Можно ли определить синонимы / псевдонимы для макросов в Clojure? Требуется ли использовать defmacro?

Ответы [ 3 ]

29 голосов
/ 26 августа 2009

Может звучать (линейно) шумно, но

(def #^{:macro true} case #'cond)

работает! * * 1004

8 голосов
/ 23 августа 2009

Вы можете использовать макрос:

user=> (defmacro def-function [& args] `(defn ~@args))
#'user/def-function
user=> (def-function g [] 2)
#'user/g
user=> (g)
2

Или вы можете использовать clojure.contrib.def/defalias:

user=> (use 'clojure.contrib.def)
nil
user=> (defalias def-function defn)
#'user/def-function
user=> (def-function g [] 2)
#'user/g
user=> (g)
2
3 голосов
/ 23 августа 2009

Для этого, по сути, вам нужно будет переписать макрос точно так же, как оригинал, просто подставив другое имя (для этого, конечно, вы должны использовать defmacro). Это единственный способ, который возможен, поскольку макросы не возвращают значение, а просто записывают код, который впоследствии должен быть оценен.

Def требует привязки имени к значению, а не к блоку кода.

(определение символа init?)

Создает и интернирует или находит глобальную переменную с именем символа и пространством имен значения текущего пространства имен ( ns ). Если указан init, он оценивается, и корневая привязка var устанавливается на результирующее значение. Если init не указан, корневая привязка var не затрагивается. def всегда применяется к корневой привязке, даже если var привязан к потоку в точке, где вызывается def. def возвращает саму переменную (а не ее значение). Выдает исключение, если символ уже находится в пространстве имен и не сопоставлен с интернированной переменной.

с Clojure: Special Forms

Макросы не оценивают свои формы:

Макросы - это функции, которые манипулируют формами, позволяя использовать синтаксическую абстракцию. Если оператор вызова является символом, который называет глобальную переменную, которая является макро-функцией, то эта макро-функция вызывается, и передается неоцененным формам операндов [курсив мой]. Возвращаемое значение макроса затем оценивается на его месте.

от Clojure: Оценка

В общем, смысл макроса в том, чтобы задержать оценку, поэтому он не может предоставить значение для def для привязки к символу.

...