gpt4 book ai didi

clojure - 在宏中创建命名空间限定函数名称

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

我有一堆函数映射到外部系统定义的某些代码或从外部系统定义的一些代码映射:

(defn translate-from-ib-size-tick-field-code [val]
(condp = val
0 :bid-size
3 :ask-size
5 :last-size
8 :volume))

(defn translate-to-ib-size-tick-field-code [val]
(condp = val
:bid-size 0
:ask-size 3
:last-size 5
:volume 8))

我想制作一个宏来删除重复项:

#_ (translation-table size-tick-field-code
{:bid-size 0
:ask-size 3
:last-size 5
:volume 8})

我像这样启动了宏:

(defmacro translation-table [name & vals]
`(defn ~(symbol (str "translate-to-ib-" name)) [val#]
(get ~@vals val#)))

生成的函数体看起来是正确的,但函数名称是错误的:

re-actor.conversions> (macroexpand `(translation-table monkey {:a 1 :b 2}))
(def translate-to-ib-re-actor.conversions/monkey
(.withMeta (clojure.core/fn translate-to-ib-re-actor.conversions/monkey
([val__10589__auto__]
(clojure.core/get {:a 1, :b 2} val__10589__auto__))) (.meta ...

我希望“translate-to-ib-”作为函数名称的一部分出现,而不是事实证明是命名空间的前缀。

如何使用 clojure 宏来做到这一点?如果我只是做错了并且出于某种原因不应该使用宏,请告诉我,但我也想知道如何创建这样的函数名称以提高我对 clojure 和宏的理解。谢谢!

最佳答案

宏观问题是双重的:

1) 在引用传递给 macroexpand 的表单时使用反引号,该表单对其中的符号进行命名空间限定:

`(translation-table monkey {:a 1 :b 2})
=> (foo.bar/translation-table foo.bar/monkey {:a 1, :b 2})

其中 foo.bar 是您所在的命名空间。

2) 您正在使用符号 name 构造 defn 项的名称,当它是命名空间限定的时,它将字符串化为“foo.bar”/猴”。这是一个可以使用的版本:

(defmacro translation-table [tname & vals]
`(defn ~(symbol (str "translate-to-ib-" (name tname))) [val#]
(get ~@vals val#)))

请注意,我们使用 name 函数获取不带命名空间部分的 tname 名称。

至于宏是否是正确的解决方案,可能不是:-)对于像这样的简单情况,我可能只使用 map :

(def translate-from-ib-size-tick-field-code 
{0 :bid-size
3 :ask-size
5 :last-size
8 :volume})

;; swap keys & vals
(def translate-to-ib-size-tick-field-code
(zipmap (vals translate-from-ib-size-tick-field-code)
(keys translate-from-ib-size-tick-field-code)))

(translate-from-ib-size-tick-field-code 0)
=> :bid-size

(translate-to-ib-size-tick-field-code :bid-size)
=> 0

如果速度至关重要,请查看案例

关于clojure - 在宏中创建命名空间限定函数名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7650458/

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