gpt4 book ai didi

clojure - 在 Clojure 中映射符号绑定(bind)宏(在 fn 中)

转载 作者:行者123 更新时间:2023-12-04 01:49:38 28 4
gpt4 key购买 nike

我定义了一个宏来将从字符串派生的符号绑定(bind)到字符串,如下所示:

lein repl
... Clojure 1.8.0 ...
user=> (defmacro foo [s] `(def ~(symbol s) ~s))
#'user/foo

它在顶层调用时按预期工作:

user=> (foo "asdf")
#'user/asdf
user=> asdf
"asdf"

但是当我尝试映射一个在序列上调用宏的函数时,宏绑定(bind)了函数参数符号而不是我想要的:

user=> (map (fn [x] (foo x)) ["qwer"])
(#'user/x)
user=> x
"qwer"
user=> qwer
CompilerException ... Unable to resolve symbol: qwer ...

以下替代方法绑定(bind)了 Clojure 创建的临时符号:

user=> (map #(foo %) ["qwer"])
(#'user/p1__1253#)

正如我在 StackOverflow 上研究的一些现有答案所建议的那样,它在包裹在 doall 中时也不起作用。

我如何定义一个可以映射(在函数或其他方式中)字符串集合的符号绑定(bind)宏?

最佳答案

map 是一个函数,foo 是一个宏。由于宏扩展发生在编译时,函数在运行时执行,因此定义一个可以映射(并因此在运行时扩展)的符号绑定(bind)宏是不可能的。

你可以做的是这样的:

(defn foo2 [s]
`(def ~(symbol s) ~s))

(defmacro foos [ss]
`(do ~@(map foo2 ss)))

(foos ["asdf" "qwer"])

asdf ;; => "asdf"
qwer ;; => "qwer"

现在情况正好相反:使用函数 mapfoo 扩展宏。

关于clojure - 在 Clojure 中映射符号绑定(bind)宏(在 fn 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41352862/

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