我正在尝试编写一个函数,它接受一系列绑定和一个表达式并返回结果。
绑定序列的格式如下:([: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
通常是不好的做法。我不相信我可以把它写成宏,因为绑定和表达式可能只在运行时给出,所以我要问的是:有没有更惯用的方法呢?
答案 0 :(得分:2)
eval
几乎总是不是答案,尽管有时会发生罕见的事情。在这种情况下,您符合条件,因为:
因为绑定和表达式只能在运行时给出
因此,至少在我理解问题的情况下,使用eval的现有示例是适当的。也许有空间可以改变要求以允许提前定义表达式并消除对eval的需求,但如果没有,那么我建议使用你拥有的。