2014-01-15 39 views
1

我想寫一個宏,我可以用它來調用一個新線程上的函數,並打印該函數的名稱以及運行它之後的線程名稱。與clojure宏有問題

到目前爲止,我所擁有的是:

 (defmacro start-threads [f] 
     '(let [t (Thread. 'f)] 
      (prn (str "running " 'f " on: " (.getName t))))) 

,當我運行:

(start-threads funcname) 

輸出: 「上運行F:螺紋-47」。我希望它輸出:「運行funcname:Thread-47。當我嘗試去引用它時,試着評估函數。我知道我沒有運行.start在這裏的線程,但我應該能夠添加在這之後,我確信一個宏並不是完全必要的,因爲我只是開始考慮clojure中的宏是如何工作的,所以我主要想知道好奇心。

+0

錯誤的單引號。 –

回答

6

基本上,你想要的是語法-quote而不是正常的報價。

(defmacro start-threads [f] 
    `(let [t# (Thread. ~f)] 
    (prn (str "running " '~f " on: " (.getName t#))))) 

~f在語法引號內插的f值,'~f引號是值和t#使得自動gensym所以VAR易名與任何周邊名稱不會發生衝突。

但正如你正確地指出,你真的不需要這個宏。它可能很容易成爲一個功能:

(defn start-threads [f] 
    (let [t (Thread. f)] 
    (prn (str "running " f " on: " (.getName t))))) 
+0

謝謝,這絕對有幫助。我想我想要的一件事就是不用獲取函數的字符串表示形式,它看起來像[email protected],我想要輸入的實際文本作爲宏的參數。所以(啓動線程寫入線程)會輸出「正在運行寫入線程:Thread-47」。顯然不是什麼大不了的,我只是好奇如何做到這一點。 –

+0

@SeanGeoffreyPietz:啊,我明白了。好的,我已將代碼更改爲以這種方式工作。唯一的區別是你只需要引用第二個'〜f'。而*就是你需要一個宏來做的事情,因爲參數將在它們傳遞給它的函數執行之前被評估。 – Chuck