在Clojure中,宏如何与函数不同?

Amo*_*kar 7 clojure

我刚刚开始使用宏并制作一个简单的宏来从列表中返回最大数量.

(defmacro macro-max [list] (apply max list))
Run Code Online (Sandbox Code Playgroud)

如果我做一个函数来做同样的事情,那就是.

(defn  macro-max [list] (apply max list))
Run Code Online (Sandbox Code Playgroud)

我正在探索Clojure,所以我不太了解.

我可能听起来对专家来说很傻,但看起来我几乎可以定义一个函数而不是宏.

leo*_*ges 7

除非需要,否则当您不想评估您的参数时,差异就会变得生动.

考虑这个例子:

(defn unless [pred body]
  (when (not pred)
    body))
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为热切地评估函数的参数.所以身体总是运行,如下所示:

(unless (zero? 2)
        (prn "Not zero!"))
;; "Not zero!"

(unless (zero? 0)
        (prn "Not zero!"))
;; "Not zero!"
Run Code Online (Sandbox Code Playgroud)

上面的两个执行都打印出"非零!",这显然是错误的.

编写unless实用程序的唯一方法是使用宏:

(defmacro unless [pred body]
  `(when (not ~pred)
     ~@body))
Run Code Online (Sandbox Code Playgroud)

现在,如果我们尝试一下,我们会看到它按预期工作:

(unless (zero? 2)
        (prn "Not zero!"))
;; "Not zero!"

(unless (zero? 0)
        (prn "Not zero!"))
;; this prints nothing
Run Code Online (Sandbox Code Playgroud)

宏只在开发人员决定时评估其参数.

您会注意到宏中的一些特殊字符,例如`,〜和〜@.它们分别代表语法引用,不引用和非引用拼接,并在此处进行解释.

我建议你学习这些符号.

希望这可以帮助.