如何将列表表单转换为clojure中的函数

如何将列表表单转换为clojure中的函数,第1张

概述我有一个像这样定义的函数规范,我想将它评估为一个函数对象,所以我可以传递. (def spec '(foo [n] (* 2 n))) 我可以像这样创建一个宏 (defmacro evspec [name arg & body] `(defn ~name [~arg] ~@body)) 然后以下调用将给我函数foo.当用3调用时,(foo 3)将返回6. (evspec foo n (* 2 n) 我有一个像这样定义的函数规范,我想将它评估为一个函数对象,所以我可以传递.

(def spec '(foo [n] (* 2 n)))

我可以像这样创建一个宏

(defmacro evspec [name arg & body] `(defn ~name [~arg] ~@body))

然后以下调用将给我函数foo.当用3调用时,(foo 3)将返回6.

(evspec foo n (* 2 n))

但是,如果我从上面定义的规范中获取函数体,则返回的函数foo不会评估体形(* 2 n),而是返回体形.

(let [foo (first spec) arg (first (second spec)) body (last spec)]  (evspec foo arg body))user=> (foo 3)(* 2 n)

我注意到现在创建的foo函数是$eval $foo

user=> foo#<user$eval766$foo__767 user$eval766$foo__767@39263b07>

而工作foo功能是

user=> foo#<user$foo user$foo@66cf7fda>

任何人都可以解释为什么会有差异,我怎样才能使它发挥作用?我想在没有回复eval的情况下有办法吗?来自JavaScript背景,不知怎的,我总是认为eval是邪恶的.

解决方法 没有评估,一般不可能做到这一点.宏只是一个函数,它在编译时从字面上传递它的参数表达式(通常根本不可能知道它们的值在运行时可能是什么).特别是,在问题文本中let表单内的evspec调用中,返回值为(* 2 n),evspec宏扩展器在字面上看到符号foo和符号n作为其位置参数和(body)(包含单个符号体的seq作为其“rest”参数;返回值与这些输入一致.

但是,使用eval来达到这种目的是非常好的.重要的是要记住它具有相当大的运行时成本,因此您需要稍微使用它,但是一旦使用eval生成函数,它就是一个非常好的Clojure函数,就像其他任何函数一样快.

另外,请注意,在JavaScript eval对文本进行 *** 作时,Clojure的eval在Clojure数据结构上运行 – 实际上相同的数据结构宏运行 – 这可以说它不易出错.

总结

以上是内存溢出为你收集整理的如何将列表表单转换为clojure中的函数全部内容,希望文章能够帮你解决如何将列表表单转换为clojure中的函数所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1064785.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存