我刚开始学习宏,制作了一个简单的宏来返回列表中的最大数。
(defmacro macro-max [list] (apply max list))
如果我编写一个函数来实现同样的功能,它将是:
(defn macro-max [list] (apply max list))
我只是在探索Clojure,所以并不了解太多。
对于专家来说,我可能听起来很傻,但似乎我可以定义一个函数代替宏。
我刚开始学习宏,制作了一个简单的宏来返回列表中的最大数。
(defmacro macro-max [list] (apply max list))
如果我编写一个函数来实现同样的功能,它将是:
(defn macro-max [list] (apply max list))
我只是在探索Clojure,所以并不了解太多。
对于专家来说,我可能听起来很傻,但似乎我可以定义一个函数代替宏。
当你不想评估参数除非必要时,区别就体现出来了。
考虑以下例子:
(defn unless [pred body]
(when (not pred)
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
宏只在开发者决定时才评估其参数。
您会注意到宏中的一些特殊字符,例如“`”,“~”和“~@”。它们分别代表语法引用、取消引用和取消引用拼接,并在此处进行了解释。
我建议您学习这些符号。
希望对您有所帮助。
->>
宏为例:(->>
"abcdefghij"
(take 5)
(drop 3)
(apply str))
(take 5)
时会引发错误,因此函数无法实现该功能。宏是函数。不同之处在于评估时间(宏在宏展开时评估,这是编译的一步,而函数在运行时评估)。此外,宏作用于S表达式(因此宏有点像一个函数,在其中引用每个单独的参数,即您可以轻松地将任何宏(mac a b)
替换为函数(fun'a' b)
。
(mac a b)
替换为函数(fun 'a 'b)
。但实际上并不容易。要使其正常工作,要么a)函数需要在调用者的上下文中解析符号,要么b)调用者必须在自己的上下文中eval
函数的结果。b)更接近宏的实际工作方式。 - Rafał Dowgird我没有宏的经验,但它可以让你通过自己的函数扩展编译器。我不确定,但它是在运行时评估的。
没有经验
并且不确定
,为什么还要回答呢? - Matteo Tassinari