Dynamic 带类型暗示的动态函数
我试图在运行时生成带有暗示参数的函数 参数符号在运行时是已知的 如果我事先知道它们,我可以动态创建如下函数:Dynamic 带类型暗示的动态函数,dynamic,clojure,metadata,eval,Dynamic,Clojure,Metadata,Eval,我试图在运行时生成带有暗示参数的函数 参数符号在运行时是已知的 如果我事先知道它们,我可以动态创建如下函数: (def foo (eval (list 'fn '[^String a] (list '.length 'a)))) 具有理想性能的: user=> (time (reduce + (map foo (repeat 1000000 "asdf") ))) "Elapsed time: 164.578 msecs" 4000000 与之相反: (def bar
(def foo
(eval
(list 'fn '[^String a] (list '.length 'a))))
具有理想性能的:
user=> (time (reduce + (map foo (repeat 1000000 "asdf") )))
"Elapsed time: 164.578 msecs"
4000000
与之相反:
(def bar
(eval
(list 'fn '[a] (list '.length 'a))))
user=> (time (reduce + (map bar (repeat 1000000 "asdf") )))
"Elapsed time: 2392.271 msecs"
4000000
现在。我遇到的问题是如何在运行时使用动态参数列表创建这样的函数。例如:
(def baz
(let [args '[a b]]
(eval
(list
'fn
(vec (flatten (map (fn [ar] `[^String ~ar]) args)))
(list '.length (first args))))))
#'user/baz
user=> (time (reduce + (map baz (repeat 1000000 "asdf") (repeat 1000000 "asdf"))))
"Elapsed time: 2467.178 msecs"
4000000
语法引号似乎阻止编译器或读取器宏解释类型暗示。
如何使用类型提示实现动态函数生成
另外,我知道这样的函数创建看起来很疯狂,有人可能会建议使用宏而不是eval,但我有充分的理由这样做
p.p.S除了使用特殊形式“fn”和eval之外,还有其他方法可以使用运行时已知的参数创建lambda吗 如果你坚持:
(defn bazy [arglist]
(let [args (mapv #(with-meta (symbol %) {:tag 'String}) arglist)]
(eval (list 'fn args (list '.length (first arglist))))))
(def baz (bazy '[a b]))
德拉特。键盘太慢了。请注意,通过不计算参数(通过引用)和计算结果,您实际上是在运行时而不是(宏)编译时执行宏的工作。非常感谢a.Webb。这正是我想要的。其动机是我将很快开放源代码的库。它是自动算法微分工具。定义要区分的表达式的代码在编译时是未知的,因为它将通过JavaDSL定义。还有纯clojure用法,可以使用宏。^是一个读卡器宏,因此^String应用于~ar,eval从未见过。不理解您的P.P.S.问题或其动机。在大多数情况下,更高阶函数(在本例中为返回函数的函数)是首选。也许你可以用一个新问题来阐述你的想法?