Можно ли безопасно игнорировать разницу между макросом и встроенным? - PullRequest
7 голосов
/ 25 февраля 2011

Я начинаю с Clojure, который также является моим первым языком. Очевидно, что многое нужно принять, и в попытке уменьшить когнитивную нагрузку я пытаюсь найти части, которые я могу спокойно игнорировать (пока).

Можно ли безопасно обрабатывать формы с помощью макросов, а формы с помощью встроенных модулей одинаково, или есть ошибки, которые возникнут позже?

Другими словами, буду ли я когда-нибудь сталкиваться с ситуацией, когда мне нужно будет знать, что (defn f1 []) расширяется до

(def f1 (.withMeta (clojure.core/fn f1 ([])) (.meta (var f1))))

Ответы [ 3 ]

9 голосов
/ 25 февраля 2011

Макросы в целом составляются совсем по-другому.Макросы не являются «гражданами первого класса»: вы не можете передать их map и т. Д., Вы не можете хранить их в переменных и apply их в список аргументов.Изначально вам не нужно беспокоиться об этом, потому что они , очевидно, не сработают: едва заметная, трудно обнаруживаемая ошибка будет гораздо более тревожной.Если вы попытаетесь запустить

(map if [true false true false] [1 2 3 4] [-1 -2 -3 -4])

, то тот факт, что if является , а не функцией , станет очень очевидным.Просто имейте в виду, что макросы не являются функциями, и с вами все будет в порядке:)

PS: макросы (fn (fn (fn :-D) :^P) :O)

7 голосов
/ 26 февраля 2011

Почти во всех случаях вы можете полностью игнорировать это различие. (и на самом деле, так как fn не является встроенным - это макрос, расширяющийся до fn *)

Единственное исключение, с которым я столкнулся, это то, что макросы и встроенные модули ведут себя по-разному, если вы пытаетесь переопределить их. Только не переопределяйте существующие функции, и вы будете хорошо относиться к ним так же.

1 голос
/ 25 февраля 2011

Я сам новичок в Clojure, но немного больше времени испытываю язык.

Я могу сказать, что встроенные макросы Clojure очень безопасны, так как вы можете использовать их, даже не зная, что они являются макросами..

В частности, поскольку Clojure уделяет гораздо больше внимания неизменности, чем Common Lisp, вам труднее попасть в ошибку, вызванную ошибочным макросом.

Так что нет, вы не будетестолкнуться с ситуацией, когда вам нужно знать о внутренностях встроенного макроса.Но если вы хотите выяснить внутренности своего собственного макроса, всегда есть macroexpand .

...