clojure.core:. оператор, defmacro и setMacro - PullRequest
4 голосов
/ 13 июля 2011

Просматривая файл clojure.core после определения defmacro, вы получаете следующий код:

(. (var defmacro) (setMacro))

Что это значит и делает?

Ответы [ 3 ]

6 голосов
/ 13 июля 2011

Значение . объясняется ответами Джоста и Джереми. На случай, если вам интересно узнать, что достигается этим конкретным вызовом метода:

В основном это вставляет ключ с именем :macro со значением true в карту метаданных Var, имя которого clojure.core/defmacro. Результатом этого является то, что с этого момента, если компилятор встречает символ defmacro в контексте, где он разрешается в var #'clojure.core/defmacro (#'foo является сокращением для (var foo)) - который обычно будет везде хотя вы могли бы, например, замаскируйте этот Var с помощью локальной переменной let - он будет знать, что он должен обращаться с ним соответствующим образом в случае имени макроса.

(То есть, либо (1) разверните вызов макроса, используя функцию, связанную с #'clojure.core/defmacro, если символ defmacro находится в позиции оператора, т. Е. Непосредственно справа от открывающей пары, либо же бросьте исключение, чтобы жаловаться на упоминание имени макроса в позиции без оператора.)

Между прочим, компилятор Clojure обычно использует такого рода карты метаданных на Vars, например, принять решение о типах различных объектов (см. :tag метаданные) или о необходимости встроить вызов функции (IIRC, :inline и :inline-arities).

2 голосов
/ 13 июля 2011

Я сломаю всю строку, так как я не знаю, что вы уже знаете.

Во-первых, документация для var гласит:

Символ должен преобразовываться в var, и возвращается сам объект Var (не его значение).

Если мы введем это в REPL, мы получим:

user=> (var defmarco)
#'clojure.core/defmacro

Теперь специальная форма . позволяет вызывать методы для экземпляров объектов Java . В этом случае вызывается метод setMacro для возвращенного объекта Var.

Я недостаточно знаком с кодом, чтобы по-настоящему понять, что делает setMacro, но я понял, что он изменяет состояние переменной, говоря, что это макрос, а не функция или что-то еще.

1 голос
/ 13 июля 2011

(. Foo (bar)) является низкоуровневым эквивалентом (.bar foo), поэтому при вызове defmacro var вызывается метод setMacro без аргументов.

Я подозреваю, что этот вызов отмечает defmacroФункция / var как макрос.В общем, многие вещи в clojure.core используют низкоуровневые трюки для начальной загрузки языка, так что, хотя интересно посмотреть, как создаются вещи, это не совсем хороший источник идиоматического кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...