2012-02-07 13 views
5

Estoy tratando de definir una macro para definir las constantes de tiempo de compilación sintaxis para que se añadió en Clojure 1.3:definición constante en Clojure

==^2.14: defs const ==

^: const le permite nombrar valores primitivos con referencia más rápida.

(def constantes {: PI 3,14: e 2,71}) ​​

(def ^: pi const (: constantes pi)) (def ^: const E (: e constantes))

La sobrecarga de buscar: e y: pi en el mapa se produce en compilar tiempo, como (: constantes pi) y (: constantes e) se evalúan cuando se evalúan sus formularios de definición primaria .

Básicamente quiero un poco de azúcar sintaxis alrededor (def ^:const ... ...), así que estoy tratando de hacerlo de esta manera:

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

Pero esto no funciona:

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

Por lo que reunir el atajo de meta #^<...> es una macro de lector, y para definir una macro que agrega algunos metadatos a algo, uno debe usar (with-meta ...).

No he encontrado ninguna documentación con respecto a ^:const. ¿Esta construcción sintáctica incluso crea algún tipo de metadata? Siguiendo el ejemplo no muestra ninguna:

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

Respuesta

10

El primer problema es que está examinando los metadatos de 3.14. Use (meta (var pi)) para ver los metadatos de pi. Si lo hace, verá que incluye :const true.

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

reproduce con precisión los metadatos y el rendimiento de ^:const (el código es una adaptación de la fuente de defn-).

+0

Gracias por la respuesta. Comprobé haciendo '(tiempo (puntos débiles [_ 1e10] (* pi pi)))' contra '(tiempo (puntos débiles [_ 1e10] (* 3.14 3.14)))' y equivale al mismo tiempo de ejecución. – MisterMetaphor

+0

Interesante. Me perdí el punto de 'const' - No entendí que' const' "vars" tenga una búsqueda más eficiente. Tienen mucho más sentido, ahora. – Retief

Cuestiones relacionadas