Macros 文本标记中的本地上下文

Macros 文本标记中的本地上下文,macros,clojure,Macros,Clojure,文字标记是否可以捕获本地上下文绑定,例如,如果我有一个标记#my/closuretag,其读取器函数是closuretag (defrecord MyRecord [f]) (defn closuretag [f] (MyRecord. (eval f))) 对于上述定义,#my/closuretag inc可以正常工作,但 (让[foo 1]#my/closuretag#(inc-foo))将失败 文本标记是否可以用于这种情况?可以通过宏而不是普通的读卡器函数执行 编辑: 这里有点奇怪,如果

文字标记是否可以捕获本地上下文绑定,例如,如果我有一个标记#my/closuretag,其读取器函数是
closuretag

(defrecord MyRecord [f])
(defn closuretag [f] (MyRecord. (eval f)))
对于上述定义,
#my/closuretag inc
可以正常工作,但
(让[foo 1]#my/closuretag#(inc-foo))
将失败

文本标记是否可以用于这种情况?可以通过宏而不是普通的读卡器函数执行

编辑:


这里有点奇怪,如果我将
closuretag
函数更改为
(defn closuretag[f]f)
,我会得到一个适当的闭包,在函数内部绑定了作用域变量,该函数是可调用的!为什么在这里使用记录会导致f成为符号列表

我猜想,我们应该从文字标记与标记元素以及编辑中描述的行为推断,您指的是安装在
data\u readers.clj
中的读卡器,而不是通过(edn/)
读取
读取字符串的读卡器

因为它们是读取器函数,所以它们的行为类似宏,因为您可以在概念上考虑要引用的参数,并将结果作为代码进行评估。 那么,你想要这个

(defrecord MyRecord [f])

(defn my-tag-reader [f] (list ->MyRecord f))
要了解这种行为

(def my-record (let [foo 1] #my/example-tag #(inc foo)))

((:f my-record)) ;=> 2

my tag reader
data\u readers.clj
map中
#my/example tag
的(命名空间限定的)reader函数时。

为什么你这么肯定这个问题是由使用
defrecord
引起的,而不是由使用
eval
引起的?@leonideschastny hurm不确定,我在这里可能完全错了,但是我不能用宏来代替函数。因此,评估符号列表最明显的方法是使用eval,我就是这么做的。我不清楚(对我来说)你想做什么,但是(1)
eval
看不到本地上下文,(2)在数据读取器函数中使用
eval
是个坏主意。其中一点是保护读者在阅读过程中不受意外/恶意代码评估的影响,在您阅读的任何内容上使用
eval
都会否定这种安全性。@A.Webb您能解释一下这里不清楚的地方吗?如果它有帮助的话,我还放了一些代码片段来清楚地演示这个问题。如果我的文章不清楚,我们可以继续。一些用法示例和对想要这样做的动机的描述对我会有帮助。我真的不清楚,这里发生了什么,但是你所说的只需稍加修改即可将MyRecord
更改为
->MyRecord
。所以这确实是clojure的一个阴暗的地方,它位于宏和简单函数之间。对,忘了反映我在本地进行的编辑(现在通过编辑修复)。据我所知,这是一个面向读者的函数,因此它将代码视为数据,并将数据生成为代码,在求值之前进行转换。