2015-11-02 16 views
6

In Common Lisp, posso definire e utilizzare una macro che acquisisce una variabile da scope lessicale, in modo che possa utilizzare in una forma let:Come acquisire in ambito lessicale in una macro Clojure?

CL-USER> (defmacro plus9() `(+ 9 woo)) 
PLUS9 
CL-USER> (macroexpand '(plus9)) 
(+ 9 WOO) 
T 
CL-USER> (let ((woo 1)) (plus9)) 
10 

Tuttavia, quando definisco una macro simile a Clojure, è alla ricerca di una definizione di woo nel user namespace:

user=> (defmacro plus9 [] `(+ 9 woo)) 
#'user/plus9 
user=> (macroexpand '(plus9)) 
(clojure.core/+ 9 user/woo) 
user=> (let [woo 1] (plus9)) 

CompilerException java.lang.RuntimeException: No such var: user/woo 

Chiaramente che sto equivoco come ambiti di lavoro in Clojure. Qual è il modo corretto di raggiungere questa macro con Clojure?

+1

http://hubpages.com/technology/Unhygenic-anaphoric-Clojure-macros-for-fun-and-profit – coredump

+1

Sintassi citando in Clojure è specificamente progettato per * evitare * collisioni di nomi di simboli citati con nomi con lessicalismo, sulla base della teoria che questi sono tipicamente non intenzionali. Come illustrato nella risposta, devi fare un lavoro extra se è quello che stai cercando di fare. – Alex

risposta

8

Sono un noob macro, ma come su

user=> (defmacro plus9 [] `(+ 9 ~'woo)) 
#'user/plus9 
user=> (macroexpand '(plus9)) 
(clojure.core/+ 9 woo) 
user=> (let [woo 1] (plus9)) 
10 
+3

Sì. è così che si cattura una legatura lessicale in clojure. sintassi-preventivo qualificherà i simboli in base allo spazio dei nomi, assicurando così l'igiene. Per questo motivo, '~ '' è considerato un odore di codice e in modo idiomatico, si passa il simbolo per essere catturato nella macro: '' '(defmacro plus9 [sym]' (+ 9 ~ sym)), let [x 1] (più 9 x)) '' ' – Bendlas

Problemi correlati