Se scrivo una macro che utilizza il collegamento per creare un gensym che viene quindi associato come una variabile globale, lo stesso simbolo viene generato ripetutamente. Tuttavia, funziona correttamente se chiamo gensym
manualmente. Molto semplici esempi:(gensym) è sempre univoco, `(symb #) non lo è - perché?
(defmacro indirection
[name & body]
`(do (def name# [email protected])
(defn ~name [] name#)))
(indirection foo 3)
(foo) ; ⇒ 3
(indirection goo 5)
(goo) ; ⇒ 5
(foo) ; ⇒ 5
Il problema è evidente se si utilizza macroexpand
:
(macroexpand '(indirection foo 3))
(do (def name__2863__auto__ 3) (clojure.core/defn foo [] name__2863__auto__))
(macroexpand '(indirection foo 3))
(do (def name__2863__auto__ 3) (clojure.core/defn foo [] name__2863__auto__))
Questo problema va via se chiamo gensym
la strada più lunga:
(defmacro redirection
[name & body]
(let [rename (gensym)]
`(do (def ~rename [email protected])
(defn ~name [] ~rename))))
(redirection koo 3)
(koo) ; ⇒ 3
(redirection moo 5)
(moo) ; ⇒ 5
(koo) ; ⇒ 3
Quindi, perché la differenza? Cosa mi manca?
'foo #' è una specie di macro che viene sostituita prima che la definizione della macro venga elaborata? – galdre