Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dynamic 带类型暗示的动态函数_Dynamic_Clojure_Metadata_Eval - Fatal编程技术网

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.问题或其动机。在大多数情况下,更高阶函数(在本例中为返回函数的函数)是首选。也许你可以用一个新问题来阐述你的想法?