我正在尝试编写一个函数,它接受一系列绑定(bind)和一个表达式并返回结果。
绑定(bind)序列的格式如下:([:bind-type [bind-vec] ... )
其中,bind-type 是 let 或 letfn。例如:
([:let [a 10 b 20]] [:letfn [(foo [x] (inc x))]] ... )
该表达式只是一个常规的 Clojure 表达式,例如(foo (+ a b))
因此,这个示例输入对加在一起将产生 31。
目前我有这个:
(defn wrap-bindings
[[[bind-type bind-vec :as binding] & rest] expr]
(if binding
(let [bind-op (case bind-type :let 'let* :letfn 'letfn*)]
`(~bind-op ~bind-vec ~(wrap-bindings rest expr)))
expr))
(defn eval-with-bindings
([bindings expr]
(eval (wrap-bindings bindings expr))))
我对 Clojure 的经验不是很丰富,并且被告知使用 eval
通常是不好的做法。我不相信我可以将其编写为宏,因为绑定(bind)和表达式只能在运行时给出,所以我要问的是:是否有更惯用的方法来执行此操作?
最佳答案
eval
几乎总是不是答案,尽管有时会发生罕见的事情。在这种情况下,您符合标准,因为:
since the bindings and expression may only be given at run-time
- 您希望在程序运行时输入并运行任意代码
- 要使用的绑定(bind)表单可以接受任何数据作为输入,甚至可以是来自程序中其他位置的数据
因此,考虑到问题的限制,至少按照我的理解,您使用 eval 的现有示例是合适的。也许有空间可以更改要求,以允许提前定义表达式并消除对 eval 的需要,但如果没有,那么我建议使用您拥有的。
关于clojure - 使用本地绑定(bind)函数进行评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48911553/