gpt4 book ai didi

clojure - 在 Clojure 中嵌套宏

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

考虑这个伪代码:

(defrc name
"string"
[a :A]
[:div a])

defrc 将是一个宏,它将扩展为以下内容

(let [a (rum/react (atom :A))]
(rum/defc name < rum/reactive []
[:div a]))

其中 rum/defc 本身就是一个宏。我想出了下面的代码:

(defmacro defrc
[name subj bindings & body]
(let [map-bindings# (apply array-map bindings)
keys# (keys map-bindings#)
vals# (vals map-bindings#)
atomised-vals# (atom-map vals#)]
`(let ~(vec (interleave keys# (map (fn [v] (list 'rum/react v)) (vals atomised-vals#))))
(rum/defc ~name < rum/reactive [] ~@body))))

几乎可行:

(macroexpand-all '(defrc aname
#_=> "string"
#_=> [a :A]
#_=> [:div a]))
(let* [a (rum/react #object[clojure.lang.Atom 0x727ed2e6 {:status :ready, :val nil}])] (rum/defc aname clojure.core/< rum/reactive [] [:div a]))

但是当使用它时会导致语法错误:

ERROR: Syntax error at (clojure.core/< rum.core/reactive [] [:div a])

是不是内部宏没有展开?

最佳答案

事实证明宏工作正常,但出现问题是因为 < 位于语法引号内,它被扩展为 clojure.core/<,而 Rum 只是从 Rum 的源代码中查找引用的 <,相关片段:

...(cond
(and (empty? res) (symbol? x))
(recur {:name x} next nil)
(fn-body? xs) (assoc res :bodies (list xs))
(every? fn-body? xs) (assoc res :bodies xs)
(string? x) (recur (assoc res :doc x) next nil)
(= '< x) (recur res next :mixins)
(= mode :mixins)
(recur (update-in res [:mixins] (fnil conj []) x) next :mixins)
:else
(throw (IllegalArgumentException. (str "Syntax error at " xs))))...

关于clojure - 在 Clojure 中嵌套宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34372904/

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