2011-10-27 123 views
2

確定具體化的一部分,讓我們試着直接得到這樣的:我的最終目的是提供一個宏作爲API給用戶,這將是這樣的:動態讓形式在宏

(defscript [a b] 
    (println a)) 

結果有是一個Script協議的一個實例,它看起來像:

(defprotocol Script 
    (run [this model])) 

這個想法是,第一個參數defscript是需要在model綁定到相應鍵的符號的列表:

(.run (defscript [a b] (println a)) {:a 1}) ;; yields 1 

我不能拿出能有效地產生這樣的效果的任何代碼,因爲我不斷地擊中牆壁試圖使用model參數時,因爲在宏展開時,它只是一個符號:

(defmacro invoke- 
    [params model body] 
    (let [p (flatten (map (fn [x] [x (model (keyword x))]) params))] 
    `(let [[email protected]] 
     ~body))) 

(defmacro defscript 
    [params & body] 
    `(reify Script 
    (run [~'this ~'model] 
     (invoke- ~params ~'model [email protected])))) 

invoke-工作正常,如果直接調用:

(invoke- [a] {:a 1} (println a)) ;; prints 1 

但內defscript作爲model不能正確地擴展使用時它不工作:

(.run (defscript [a] (println a)) {:a 1}) ;; prints nil 

我怎麼能通過這一點,並粘合在一起的碎片?

+0

您所描述的內容聽起來有點像clojure.template中提供的功能。 –

回答

4

看來,基本上,你的論點向量是一個解構綁定的快捷方式:

(defscript [a b] body) -> (reify Script (run [this {:keys [a b]}] body)) 

這樣,模型在運行時解體的,因爲它應該是。

+0

非常好! – kotarak

+0

純粹的迷人,謝謝! – skuro