Определение константы в Clojure - PullRequest
5 голосов
/ 07 февраля 2012

Я пытаюсь определить макрос для определения синтаксиса времени компиляции, для которого был добавлен в Clojure 1.3:

== 2,14 ^: const defs ==

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

(константы определения {: pi 3,14: e 2,71}) ​​

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

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

В основном я хочу немного синтаксического сахара вокруг (def ^:const ... ...), поэтому я пытаюсь сделать это так:

(defmacro defconst [const-name const-val]
  `(def ^:const ~const-name ~const-val))

Но это не работает:

user=> (macroexpand '(defconst pi 3.14))
(def pi 3.14)

Из того, что я понял, мета-ярлык #^<...> является макросом для чтения, и для определения макроса, который добавляет к метаданным некоторые данные, нужно использовать (with-meta ...).

Я не нашел никакой документации относительно ^:const. Создает ли эта синтаксическая конструкция какие-либо метаданные? В следующем примере ничего не показано:

user=> (def ^:const pi 3.14)
#'user/pi
user=> (meta pi)
nil

1 Ответ

10 голосов
/ 07 февраля 2012

Первая проблема заключается в том, что вы проверяете метаданные 3.14. Используйте (meta (var pi)), чтобы увидеть метаданные pi. Если вы это сделаете, вы увидите, что он включает в себя :const true.

(defmacro defconst [const-name const-val]
  `(def
    ~(with-meta const-name
       (assoc (meta const-name) :const true))
    ~const-val))

точно воспроизводит метаданные и производительность ^:const (код адаптирован из источника defn-).

...