遇到clojure宏的麻烦

Sea*_*etz 1 macros clojure

我正在尝试编写一个宏,我可以使用它来调用新线程上的函数并在运行它之后打印函数的名称以及线程的名称.

到目前为止我所拥有的是:

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

我跑的时候:

    (start-threads funcname)
Run Code Online (Sandbox Code Playgroud)

输出:"运行f:螺纹-47".我希望它输出:"运行funcname on:Thread-47.当我尝试取消它时它会尝试评估该函数.我知道我没有在线程上运行.start,但我应该能够添加在那之后.我确定宏在这里不是完全必要的,我主要是出于好奇而感到好奇,因为我刚刚开始关注clojure中的宏是如何工作的.

Chu*_*uck 6

基本上,你想要的是语法报价而不是普通报价.

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

~f在语法 - 引用中插入值的值f,'~f引用该值并t#使其成为自动gensym,因此变量名称不会与任何周围的名称冲突.

但正如你正确指出的那样,你真的不需要一个宏.它很容易成为一种功能:

(defn start-threads [f]
  (let [t (Thread. f)]
    (prn (str "running " f " on: " (.getName t)))))
Run Code Online (Sandbox Code Playgroud)