2024 Clojure 状态调查! 中分享您的想法。

欢迎!请参阅 关于 页面以了解更多关于如何使用本站的信息。

+1

我尝试在宏函数中创建一个原子并在宏输出形式中嵌入对其的引用

(defmacro x []
  (let [a (atom {})]
    `(fn []
       ~a)))

使用此宏尝试会导致此错误

`

(x)
Syntax error compiling fn* at (/tmp/form-init15982565344292085756.clj:1:1).
Can't embed object in code, maybe print-dup not defined: clojure.lang.Atom@350e9f50

`

我尝试定义一个空的 print-dup 覆载,但却产生了不同的错误

`

(defmethod print-dup clojure.lang.Atom [x w])
(x)
Syntax error compiling fn* at (/tmp/form-init15982565344292085756.clj:1:1).
Can't embed unreadable object in code: clojure.lang.Atom@5f3623b3

`

由于 Clojure 有 eval,我预计这会工作,这里有什么问题呢?

1 答案

+2

被选中
 
最佳答案

宏是接受代码并返回代码的函数。原子是具有状态的对象——在代码中使用标识符表示它们是不可能的,所以这不会工作。

您实际上尝试做什么?


编辑
>宏是接收代码并返回代码的函数。原子是包含状态的对象——在代码中没有方式用标识符来表示它们,所以这是不可行的。

我不太确定我理解的是什么意思。

>你实际想要做什么?

宏将返回一个函数,当该函数被评估时,它将修改原子值,或其他代码将读取这些值。这是一个更好的示例

  (defmacro x []
    (let [a (atom {})
          s (gensym)]
      `(fn []
         (let [~s ~a]
           ))))
上面的例子与

(defmacro x []
  (let [a (vec (range 3))
        s (gensym)]
    `(fn []
       (let [~s ~a]
        ))))

有什么不同?
  (defmacro x []
    (let [a (atom [])

         s (gensym)]

    `(fn []

您实际上尝试做什么?
...