gpt4 book ai didi

macros - Clojure - 宏中的 let 不起作用

转载 作者:行者123 更新时间:2023-12-04 23:24:30 24 4
gpt4 key购买 nike

我创建了一个宏,它创建了一个名为 dispatcher有 3 个员工职能 get-dispatcher , set-dispatchercall-dispatcher与调度员一起工作(他们得到一个调度函数,添加一个或调用一个)。一切正常!但是,现在我想自动创建相关的函数名称,因此我将宏的所有这些内部内容放入 let它定义了那个简单的构造函数。请注意,在下面的代码中只有 get-函数的名称是使用该自动化构造的。 set-call-一个人的名字创造仍然有那种手动的味道。

(defmacro create-dispatcher [name]
;creates a set of dispatching functions tagged

`(do
;define dispatcher
(def ~(symbol name) ~(atom {}))

(let
[name-w-prefix (fn [x] (~(symbol (str x "-" name))))]
; -- define getter
(defn (name-w-prefix "get")
"get-dispatcher [tag]: get a dispatcher fn by tag"
(~'[] (println "no tag is provided for '" ~(str name) "' dispatcher"))
(~'[tag]
(do
(println "dispatcher '" ~(str name) "' called with '" ~'tag "' tag")
; return the tagged dispatcher
( (keyword ~'tag) @~(symbol name) )))

)
; -- define caller
(defn ~(symbol (str "call-" name))
"get-dispatcher [tag & args]: call a dispatcher fn by tag and apply to the args"
~'[tag & args]
(apply (~(symbol (str "get-" name)) ~'tag) ~'args)
)
; -- define setter
(defn ~(symbol (str "set-" name))
~'[tag fn]
"add-dispatcher [tag fn]: add a dispatcher fn associated with the tag"
(swap! ~(symbol name) assoc (keyword ~'tag) ~'fn)
)
)

; -- report
(println "created dispatcher set for '" ~(str name) "' ok!")
))

但是,有一个问题。 name-w-prefixlet语句绑定(bind)会导致错误。我该如何解决?

(也欢迎任何关于改进的建议,因为我是新手,这几乎是我在 Clojure 中写的第一件事)

最佳答案

宏中的所有符号都在当前命名空间中解析,并期望评估为 var。您可以引用 name-w-prefix符号,但这可能会与宏扩展期间传入宏的符号发生冲突。因此,Clojure 提供了一种特殊的语法,用于以语法引用的形式生成符号 - 只需附加一个 #到符号的末尾,Clojure 会将其视为带引号的自动生成的符号。因此,在这种情况下,替换出现的 name-w-prefixname-w-prefix#你应该很高兴。

退后一步,看看你的总体目标是什么,我认为你应该移动 name-w-prefix语法引号之外的定义,然后使用语法转义来调用它。否则,你会得到更多的错误,因为 defn需要一个符号,所以一旦扩展宏必须产生一个 defn以符号作为第二项的表单。类似于以下内容:

(defmacro create-dispatcher [name]
(let [name-w-prefix #(symbol (str % "-" name))]
`(do
(def ~(symbol name) (atom {}))
(defn ~(name-w-prefix "get")
([] (println "no tag provided"))
([tag#] (println "called with tag" tag#))))))

请注意,我已更改 ~'[tag][tag#]defn body 与我上面所说的一致。

关于macros - Clojure - 宏中的 let 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15121799/

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