clojure - 在 Clojure 中,宏与函数有何不同?

标签 clojure

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

(defmacro macro-max [list] (apply max list))

如果我制作一个函数来做同样的事情,它会。
(defn  macro-max [list] (apply max list))

我只是在探索Clojure,所以我知道的不多。

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

最佳答案

除非需要,否则当您不想评估您的论点时,差异就会变得栩栩如生。

考虑这个例子:

(defn unless [pred body]
  (when (not pred)
    body))

这不起作用,因为函数的参数会被急切地求值。所以body一直在运行,如下图:
(unless (zero? 2)
        (prn "Not zero!"))
;; "Not zero!"

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

上面的两个执行都打印“非零!”,这显然是错误的。

写我们的唯一途径unless实用程序是通过使用宏:
(defmacro unless [pred body]
  `(when (not ~pred)
     ~@body))

现在,如果我们尝试一下,我们会看到它按预期工作:
(unless (zero? 2)
        (prn "Not zero!"))
;; "Not zero!"

(unless (zero? 0)
        (prn "Not zero!"))
;; this prints nothing

宏仅在开发人员决定时评估其参数。

您会注意到宏中有一些特殊字符,例如`、~ 和~@。它们分别代表语法引用、取消引用和取消引用拼接,并解释 here .

我建议你研究这些符号。

希望这可以帮助。

关于clojure - 在 Clojure 中,宏与函数有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16009015/

相关文章:

clojure - clojure中count函数的时间复杂度是多少?

Clojure - 在 map 上使用记录有什么好处

Clojure:将 group-by :key 与剩余键上的 select-key 链接起来

java - 在 Clojure/Java 中通过自定义协议(protocol)建立 HTTP 隧道

file - Clojure:等同于 Common Lisp READ 函数?

emacs - 使用 Paredit 包装现有表达式

java - 在 Eclipse 中导出单个 .jar 时避免重复库 .jars

clojure - 如何在不调用 java.lang.String 的情况下检查 clojure 中字符串的相等性?

clojure - 在clojure源码中,RT代表什么?

clojure - 如何判断http-kit客户端回调超时?