gpt4 book ai didi

macros - clojure 宏 - 不知道如何从 : clojure. lang.Symbol 创建 ISeq

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

我正在试验 clojure 宏,想知道我可能做错了什么?

我有一个简单的例子,尝试基于 map 动态创建函数。

例如:

(def units {:cm 100
:mm 1000
:m 1
:km 1/1000})

(defn m-to-unit-helper [[k v]]
(let [f (symbol (str "to-" (name k)))]
`(defn ~f [m#] (* ~v m#))))

(defmacro m-to-units [units-map]
(let [funcs (map m-to-unit-helper units-map)]
`(do ~@funcs)))

; complains with: Don't know how to create ISeq from: clojure.lang.Symbol
(m-to-units units)

; To try and debug
(defn debug [units-map]
(let [funcs (map m-to-unit-helper units-map)]
(clojure.pprint/pprint `(do ~@funcs))))

; see below
(debug units)

宏不起作用,但调试输出看起来应该创建正确的结构:
(do
(clojure.core/defn
to-mm
[m__32709__auto__]
(clojure.core/* 1000 m__32709__auto__))
(clojure.core/defn
to-m
[m__32709__auto__]
(clojure.core/* 1 m__32709__auto__))
(clojure.core/defn
to-cm
[m__32709__auto__]
(clojure.core/* 100 m__32709__auto__))
(clojure.core/defn
to-km
[m__32709__auto__]
(clojure.core/* 1/1000 m__32709__auto__)))

任何建议将不胜感激。谢谢。

最佳答案

m-to-units是一个宏,这意味着每个参数都将被传递而不被评估,这意味着在宏内部 units-map 的值实际上是符号units .

现在,如果您直接传递 map ,它将按预期工作:

 (m-to-units {:mm 1000, :m 1, :cm 100, :km 1/1000})
;; => #'user/to-km

(to-cm 10)
;; => 1000

你可以做的——虽然我认为这是不好的做法——是使用 eval获取单位映射的实际值,无论它是作为映射还是通过符号传递:
(defmacro m-to-units
[units-map]
(let [funcs (map m-to-unit-helper (eval units-map))]
`(do ~@funcs)))

(m-to-units units)
;; => #'user/to-km

关于macros - clojure 宏 - 不知道如何从 : clojure. lang.Symbol 创建 ISeq,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26684810/

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