【发布时间】:2018-02-21 17:03:52
【问题描述】:
我正在尝试编写一个函数,它接受一系列绑定和一个表达式并返回结果。
绑定序列的格式如下:([: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 通常是不好的做法。我不相信我可以把它写成一个宏,因为绑定和表达式只能在运行时给出,所以我要问的是:有没有更惯用的方法?
【问题讨论】:
-
这纯粹是一种练习吗?我看不出这在现实世界中有什么用处。
-
“绑定和表达式只能在运行时给出”但为什么不直接编写 Clojure 并在运行时加载呢?这个问题似乎你可能会不必要地重新发明 Clojure 的一个子集。
标签: clojure