gpt4 book ai didi

运行 jar 时 Clojure 宏很奇怪

转载 作者:行者123 更新时间:2023-12-04 22:58:43 25 4
gpt4 key购买 nike

下面是一个使用 lein new mw 创建的简单 Clojure 应用程序示例:

(ns mw.core
(:gen-class))

(def fs (atom {}))

(defmacro op []
(swap! fs assoc :macro-f "somevalue"))

(op)

(defn -main [& args]
(println @fs))

并在 project.clj我有
:profiles {:uberjar {:aot [mw.core]}}
:main mw.core

在 REPL 中运行时,评估 @fs返回 {:macro-f somevalue} .但是,运行 uberjar 会产生 {} .如果我改变 op定义到 defn而不是 defmacro ,然后 fs从 uberjar 运行时再次具有正确的内容。这是为什么?

我隐约意识到这与AOT编译和宏扩展发生在编译阶段之前的事实有关,但显然我对这些东西缺乏了解。

我在尝试部署使用非常好的应用程序时遇到了这个问题 mixfix库,其中使用全局原子定义 mixfix 运算符。我花了很长时间才将问题与上述示例隔离开来。

任何帮助将不胜感激。

谢谢!

最佳答案

这里真正的问题是您的宏不正确。您忘记添加反引号字符:

(defmacro op []
`(swap! fs assoc :macro-f "somevalue"))
; ^ syntax-quote ("backquote")

此操作称为语法引用,在这里非常重要,因为 clojure 中的宏会在编译期间修改您的代码。

所以,结果你得到了一个不纯的宏,修改 fs每当您的代码为 时,原子已编译 .

由于您的宏不产生任何代码, (op)在你的例子中调用什么都不做(只有 编译 做)。它似乎在 REPL 中工作,因为编译和执行由同一个 clojure 实例处理(有关详细信息,请参阅 Timur's answer)。

关于运行 jar 时 Clojure 宏很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33216456/

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