2013-01-18 67 views
1

大約一個星期前,我問了一個問題,在這個線程:Looping through a "let"-list in Clojure? 我收到了很好的回答卻是一個相當混亂的問題已經在我腦海中出現:Clojure的宏觀參數

這裏是答案的一部分:

(defmacro anaphoric-let [alternating-symbols-and-values & body] 
    `(let [[email protected] 
      names# (quote ~(flatten (partition 1 2 alternating-symbols-and-values))) 
      values# ~(vec (flatten (partition 1 2 alternating-symbols-and-values))) 
      ~'locals (zipmap names# values#)] 
     [email protected])) 


Input: 
(anaphoric-let [a 1 b 2 c 3 d 4 e "cat"] 
    (dorun (for [x (vals locals)] 
      (if (number? x) (println "roar"))))) 

這種情況下的(dorun)語句是宏參數中的正文嗎?所以我的印象是它只是「複製粘貼」身體。因此,而不是:

[email protected] 

它看起來像下面那麼這將複製的文本和所有解除引用:

[email protected](dorun (for [x (vals locals)] 
     (if (number? x) (println "roar")))) 

在我試圖努力解釋所有發生的事情,我嘗試使用的確切我剛剛解釋的事情。我沒有〜@身體,而是試圖在那裏放置一些「真實代碼」。

然後,它將是這樣的:

(defmacro anaphoric-let [alternating-symbols-and-values & body] 
    `(let [[email protected] 
      names# (quote ~(flatten (partition 1 2 alternating-symbols-and-values))) 
      values# ~(vec (flatten (partition 1 2 alternating-symbols-and-values))) 
      ~'locals (zipmap names# values#)] 
     [email protected](dorun (for [x (vals locals)] 
      if (number? x) (println "roar")))))) 

而且這並不工作,並抱怨說,它是「無法解析符號:當地人在這種情況下」 我是在這這樣的新手,我曾嘗試試驗和分析,但我不明智。每當我想到我把所有的想法都弄清楚了,總會有這個小小的「但是......」來到這裏,壓碎一切!

我覺得好像對這個例子的其餘部分有一個正確的理解,除了邪惡的〜@身體......我個人的猜測是,因爲我沒有完全理解如何將所有這些奇怪的符號,我可能會錯過它們的某種組合...

回答

1

〜@ expr在反引號表達式內意味着評估expr並將其拼接到周圍表達式

既然你需要重新評估(dorun ...)的表達,你可以複製粘貼&它來代替:

(defmacro anaphoric-let [alternating-symbols-and-values & body] 
    `(let [[email protected] 
      names# (quote ~(flatten (partition 1 2 alternating-symbols-and-values))) 
      values# ~(vec (flatten (partition 1 2 alternating-symbols-and-values))) 
      locals# (zipmap names# values#)] 
     (dorun (for [x (vals locals#)] 
      if (number? x) (println "roar")))))) 

既然你並不需要特定的符號插入到身體了,我移動替換當地人一個gensym'd符號

現在爲什麼你會想要在這樣的硬編碼宏中引入用戶指定的符號,我不知道。我假設這只是用於實驗。

+0

呵呵我實際上嘗試了一個簡單的複製和粘貼,但由於這是我第一次處理#,似乎我的錯誤並沒有在for語句中添加#。是的,我的目的不是爲了取得偉大的成就,而僅僅是在玩耍。你說這是一個我不知道的壞習慣,我想我很難真正理解宏和函數之間的差異,我一直試圖將東西翻譯成Java思路來嘗試理解它,但我想這不是非常明智的做法,因爲這不是面向對象... – Deragon

+0

但是,我試過上面的代碼,現在(anaphoric-let [a「cat」b 2])是不可能的? 「這是說錯誤的參數數量(4)通過了」 – Deragon

+1

這可能〜因爲(如果...)表達式被破壞了。你錯過了一個(之前,如果我像這樣複製,錯過了錯誤。 –