2012-01-12 25 views
3

Clojureマクロのnoobはここにあります。私はいくつかのオプションのパラメータを持つ関数を持っています。これを与える関数にオプションのマクロ引数を渡す方法

(defn mk-foo [name & opt] 
    (vec (list* name opt))) 

:私は同じオプションの引数を取り、mk-fooの呼び出しに透過的に渡すマクロを記述しようとしている

user> (mk-foo "bar" 1 2 3) 
["bar" 1 2 3] 

user> (macroexpand '(deffoo bar 1 2 3)) 
(def bar ["bar" 1 2 3]) 

不器用な感じoptリストを平坦化するapplyの使用:所望の効果を有する

(defmacro deffoo [name & opt] 
    `(def ~name ~(apply mk-foo (str name) opt))) 

:これまでのところ私はこれを持っています。これを行うための慣用的な方法はありますか?私は[email protected]が必要だと思っていますが、私は引用符を得ることができません。どうもありがとう。

+1

私はclojureにはあまりよくありませんが、 –

答えて

3

あなたの直感でこのアプリケーションを使用してください。 `引用符で囲んだフォームをしてからすべてを引用符で囲まないと、un-quotingを最小の部分またはリストに移動することについて考えるのを助けることができます。これにより、単純に記述できるフォームを生成するコードの使用を避けることができます。

user=> (defmacro deffoo [name & opt] `(def ~name [~(str name) [email protected]]))  
#'user/deffoo 
user=> (macroexpand '(deffoo "bar" 1 2 3))        
(def "bar" ["bar" 1 2 3]) 

、ここでそれはFOO-MKを呼び出している:の呼び出しを私たちは~ 1つのレベルに移動し、この後者の場合には

(defmacro deffoo [name & opt] `(def ~name (mk-foo ~(str name) [email protected])))  
#'user/deffoo 
user=> (macroexpand '(deffoo "bar" 1 2 3))         
(def "bar" (user/mk-foo "bar" 1 2 3)) 

としましょうMK-fooが引用されたとにunquoteのみ滞在しますパラメータリストを作成するために必要な引数(スプライシング・アンクォートを使用して疑わしいと思う)

+0

すばらしい答えをありがとう。残念ながら、私の実際の 'mk-foo'は、掲載されたイラストよりかなり複雑です。手でインライン展開することは選択肢ではありません。私は呼び出しを持っている必要があります。 – fizzer

+0

は、以前の編集内容の1つからmk-fooを使用した例を復活させました。 –

+0

これは+ 1で動作しますが、実行時に 'mk-foo'への呼び出しを延期することになります。 – fizzer

関連する問題