gpt4 book ai didi

clojure - 如何将可选的宏参数传递给函数

转载 作者:行者123 更新时间:2023-12-02 00:26:14 27 4
gpt4 key购买 nike

这里是 Clojure 宏新手。我有一个带有一些可选参数的函数,例如

(defn mk-foo [name & opt]
(vec (list* name opt)))

给这个:

user> (mk-foo "bar" 1 2 3)
["bar" 1 2 3]

我正在尝试编写一个宏,它采用相同的可选参数并将它们透明地传递给 mk-foo 的调用。到目前为止我有这个:

(defmacro deffoo [name & opt]
`(def ~name ~(apply mk-foo (str name) opt)))

达到预期效果:

user> (macroexpand '(deffoo bar 1 2 3))
(def bar ["bar" 1 2 3])

使用 apply 来展平列表 opt 感觉很笨拙。有没有惯用的方法来做到这一点?我猜 ~@ 是必需的,但我无法正确引用。非常感谢。

最佳答案

在这种情况下,您使用 apply 的直觉对您很有帮助。当你有一个引用形式 ` 然后取消引用所有它们时,考虑将取消引用向下移动到最小的部分或列表可能会有所帮助。这避免了使用代码生成可以简单编写的表单。

user=> (defmacro deffoo [name & opt] `(def ~name [~(str name) ~@opt]))       
#'user/deffoo
user=> (macroexpand '(deffoo "bar" 1 2 3))
(def "bar" ["bar" 1 2 3])

这是对 mk-foo 的调用:

(defmacro deffoo [name & opt] `(def ~name (mk-foo ~(str name) ~@opt)))     
#'user/deffoo
user=> (macroexpand '(deffoo "bar" 1 2 3))
(def "bar" (user/mk-foo "bar" 1 2 3))

在第二种情况下,我们将 ~ 移动到一个级别,并让对 mk-foo 的调用保持引用状态,只取消引用构建参数列表所需的 args(如您所怀疑的那样使用 splicing-unquote )

关于clojure - 如何将可选的宏参数传递给函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8842871/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com