在Clojure中,一个宏如何与一个函数不同? [英] In Clojure how is a macro different from a function?

查看:82
本文介绍了在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总是运行,如下所示:

 (除非(零?2)
(prn ))
;; 不是零!

(除非(零?0)
(prnNot zero!))
;; 不是零!

上面的两个执行都打印出不为零!,这显然是错误的。



写入我们的除非实用程序的唯一方法是使用宏:

 (defmacro unless [pred body] 
`(when(not〜pred)
〜@ body))
/ pre>

现在,如果我们尝试,我们将看到它的工作原理:

 (除非(零?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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆