我写了一个专门的函数构造,它在引擎之下实际上只是一个Clojure函数。所以基本上我有一个功能(类似于fn
)和一个调用我的专门功能的功能(类似于CL的funcall
)。有没有办法在编译时有值的元数据?
我的构造函数分配元数据(在编译时),所以我可以区分“我的”函数和其他/正常的Clojure函数。
我想要做的是制作一个宏,让用户编写代码就好像我的函数是普通函数一样。它会这样做,通过遍历代码,并在函数调用中,当被调用者是一个专门的函数时,它会改变调用,所以它会使用我的调用者(也会注入一些额外的信息)。例如:
(defmacro my-fn [args-vector & body] ...)
(defmacro my-funcall [myfn & args] ...)
(defmacro with-my-fns [& body] ...)
(with-my-fns
123
(first [1 2 3])
((my-fn [x y] (+ x y))) 10 20)
; should yield:
(do
123
(first [1 2 3])
(my-funcall (my-fn [x y] (+ x y)) 10 20))
我遇到了词汇环境中的问题。例如:
(with-my-fns
(let [myf (my-fn [x y] (+ x y))]
(myf))
在这种情况下,当我想写宏(即with-my-fns
)遇到(myf)
,它看到myf
为标志,而我没有访问元数据。这也不是一个Var,所以我不能resolve
它。
我很在乎,因为否则我必须在运行时对几乎每一个函数调用都进行检查。请注意,我并不关心这些值的元数据是否为实际的Clojure元数据;如果这种类型的系统是可能的,那么它也是一样的好。
P.S.我最初只是想问一下词汇环境,但也许还有更多的陷阱,我应该知道我的方法会失败的地方? (或者甚至上面实际上是一个XY问题?我欢迎建议)。
据我了解,你将元数据附加到运行时对象(功能)。很显然,在编译时不能访问运行时对象的元数据(不需要评估它) – OlegTheCat
@OlegTheCat是的,这就是问题所在(尽管iirc实际的Clojure元数据除了在词法环境中绑定时才工作)。在编译时没有办法让这些数据可用(通过元数据或其他方式)? – MasterMastic
为什么你不把所有的魔力放在myfun宏里面?为什么你不能在那里添加所有的检查? – murphy