Clojure константы времени компиляции - PullRequest
7 голосов
/ 10 ноября 2011

Этот вопрос исходит исключительно из "умственного мастерства" и, вероятно, не имеет практического значения.

Если я определяю значение в Clojure, используя def, можно ли заставить компилятор вычислять его во время компиляции, а не ждать до выполнения?

(def the-answer 42)

(+ the-answer 1)

Полагаю, я мог бы определить макрос, но синтаксис вызова становится неловким:

(defmacro the-answer [] 42)

(+ (the-answer) 1)

Это также работает, но все еще ужасно:

(+ `~the-answer 1)

Я также понимаю (или верю), что Clojure вычисляет константные выражения во время компиляции:

(def milliseconds-per-day (* 24 60 60 1000))

Я только изучаю Common Lisp, но, насколько я понимаю, Common Lisp поддерживает пользовательские макросы для чтения, поэтому вы можете определить макрос для чтения (что-то вроде #$), который оценивает следующий символ во время компиляции:

(+ #$the-answer 1)

Кстати, этот синтаксис не "красивее", чем вызов макроса.

Как заставить Clojure оценивать постоянные переменные во время компиляции и заменять ссылку на фактическое значение? Это уже так?

Прежде чем кто-либо начнет цитировать Закон Кнута («преждевременная оптимизация - корень всего зла»), я задаю этот вопрос, чтобы лучше понять внутреннюю часть компиляции Clojure.

Ответы [ 3 ]

11 голосов
/ 10 ноября 2011

Из документов Clojure 1.3

== 2,14 ^: const defs ==

^: const позволяет называть примитивные значения с более быстрой ссылкой.

(константы def {: pi 3.14: e 2.71})

(def ^: const pi (: pi константы)) (def ^: const e (: e константы))

Затраты на поиск: e и: pi на карте происходят во время компиляции, поскольку (: константы pi) и (: константы e) оцениваются при оценке их родительских форм def.

5 голосов
/ 10 ноября 2011

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

2 голосов
/ 14 ноября 2011

`~foo буквально идентичен foo во всех случаях - что бы вы ни думали, вы выходите из первого, это иллюзия.

Я думаю, :const, вероятно, правильный ответ, ноВы также можете использовать символьные макросы из clojure.tools.macro - для этого у него есть symbol-macrolet и defsymbolmacro / with-symbol-macros (а также для других целей).

...