我正在尝试使用提示参数在运行时生成函数。
参数符号在运行时是已知的。
如果我提前知道它们,我可以像这样动态地创建函数:
(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
看起来语法引用阻止编译器或阅读器宏解释类型提示。如何使用类型提示实现动态函数生成?
PS 我知道这样的函数创建看起来很疯狂,有人可能会建议使用宏而不是 eval,但我有充分的理由这样做。
PPS 除了特殊形式的'fn'和eval之外,还有其他方法可以使用运行时已知的参数创建lambda吗?