在Clojure中,一个宏如何与一个函数不同? [英] In Clojure how is a macro different from a function?
问题描述
(defmacro macro- max [list](apply max list))
如果我做一个函数,它将是。
(defn macro-max [list](apply max list))
我只是探索Clojure,所以我不知道多少。
我可能听起来完全愚蠢的专家,但它看起来像我几乎可以定义一个函数,而不是一个宏。
考虑这个例子:
(defn unless [pred body]
(when(not pred)
body))
这不起作用,因为函数的参数被热切地评估。所以body总是运行,如下所示:
(除非(零?2)
(prn ))
;; 不是零!
(除非(零?0)
(prnNot zero!))
;; 不是零!
上面的两个执行都打印出不为零!,这显然是错误的。
写入我们的除非
实用程序的唯一方法是使用宏:
(defmacro unless [pred body]
/ pre>
`(when(not〜pred)
〜@ body))
现在,如果我们尝试,我们将看到它的工作原理:
(除非(零?2)
(prnNot zero!))
;; 不是零!
(除非(零?0)
(prnNot zero!))
;;这不打印任何内容
宏仅在开发人员决定时评估其参数。
你会注意到宏中的一些特殊字符,如`,〜和〜@。它们分别代表syntax-quote,unquote和unquote-splicing,并在此处解释。 p>
我建议你学习这些符号。
希望这有助于。
I just started with macros and made a simple one to return maximum number out of a list.
(defmacro macro-max [list] (apply max list))
and If I make a function to do the same, it will be.
(defn macro-max [list] (apply max list))
I am just exploring Clojure, so I don't know much.
I may sound completely silly to experts, But it looks like I can pretty much define a function instead of a macro.
解决方案The difference comes to life when you don't want to evaluate your arguments unless needed.
Consider this example:
(defn unless [pred body] (when (not pred) body))
This doesn't work since arguments to a function are eagerly evaluated. So body always runs, as shown below:
(unless (zero? 2) (prn "Not zero!")) ;; "Not zero!" (unless (zero? 0) (prn "Not zero!")) ;; "Not zero!"
Both executions above print "Not zero!", which is clearly wrong.
The only way to write our
unless
utility is by using a macro:(defmacro unless [pred body] `(when (not ~pred) ~@body))
Now if we give it a try, we'll see it works as expected:
(unless (zero? 2) (prn "Not zero!")) ;; "Not zero!" (unless (zero? 0) (prn "Not zero!")) ;; this prints nothing
Macros only evaluate its arguments when the developer decides to.
You'll notice some special characters in the macro such as `, ~ and ~@. They stand for syntax-quote, unquote and unquote-splicing, respectively and are explained here.
I suggest you study these symbols.
Hope this helps.
这篇关于在Clojure中,一个宏如何与一个函数不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!