请在 Clojure 2024 年状态调查 中分享您的想法!

欢迎!请参阅 关于 页面,了解更多此空间的详细信息。

0
(defmacro test [expr]
  (letfn [(helper [expr]
            (println expr)
            (rest expr))]
    (func expr)
    (helper expr)))

(defn func [x]
 (println x))

(macroexpand '(test (+ 1 2)))

;;the evaluator prints:
;;(+ 1 2)
;;(+ 1 2)
;;(1 2)

这非常反直观,因为内部定义的函数(辅助函数)和外部(func)都通过不计算 (+ 1 2) 来表现出相似的行为。在 stackoverflow.com 上有关于此的答案(https://stackoverflow.com/questions/54394977/evaluation-of-arguments-in-function-called-by-macro),但这还不够。

1 个答案

+3

被选中
 
最佳答案

内部和外部函数的行为相同——它们接收一个列表。

计算发生在调用之前(因此不是“函数”在进行计算,而是调用它的位置)。

在这里,funchelper的参数是符号expr。符号通过在当前词法环境中解析该“名称”到值来简化。这里是在defmacro参数中定义的。它解析为一个列表(+ 1 2)。该列表被传递给函数。对这个列表进行计算将需要计算该参数两次!

宏展开不是计算,并且参数没有被计算。

非常感谢!
...