2015-11-02 7 views
6

Iはletフォーム内で使用できるように、私は、レキシカルスコープから変数を捕捉するマクロを定義して使用することができる:Clojureマクロのレキシカルスコープでのキャプチャ方法は? Common Lispでは

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

しかし、私はClojureのに似たマクロを定義するとき、それはuser名前空間にwooの定義を探しています:

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 

は、明らかに私は、スコープがClojureの中でどのように機能するかを誤解しています。 Clojureでこのマクロを達成する正しい方法は何ですか?

+1

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

+1

構文のClojureで引用これらの名前がレキシカルスコープの名前と衝突するのを避けるように特別に設計されています。答えに描かれているように、あなたがやろうとしていることがあれば余分な仕事をしなければなりません。 – Alex

答えて

8

私はマクロnoobのだけど、どの程度

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

ええ。それは、あなたがクロージャーで語彙的束縛を捕らえる方法です。 syntax-quoteは、名前空間に従ってシンボルを修飾して、衛生を保証します。そのため、 '〜 'はコードの匂いや慣用的なものとみなされます。キャプチャするシンボルを' ''(defmacro plus9 [sym] '(+ 9〜sym))、 [x 1](プラス9 x)) '' ' – Bendlas

関連する問題