我的问题是关于构造带有副作用的lisp代码。我想到的特定示例来自Clojure,但我认为它可以适用于任何lisp。
在这种情况下,我正在与需要按特定顺序调用某些函数的现有库进行交互。最后的函数调用创建了剩余程序所需的值。
代码如下所示:
(defn foo []
(let [_ procedure-with-side-effect
__ another-procedure-with-side-effect
value procedure-that-creates-the-value]
(do-something value)))
这很有效,一切都很棒,除了我认为let块看起来很可怕。有更好的方法吗?
答案 0 :(得分:9)
如果你不需要函数调用的中间值,你可以在defn
的主体中放入一堆函数调用:
(defn foo []
(procedure-with-side-effect)
(another-procedure-with-side-effect)
(do-something (procedure-that-creates-the-value)))
虽然这是此代码的最佳选择,但还有其他选择。您还可以在let
:
(let [val 3]
(fun-call-1)
(fun-call-2)
(fun-call-3 val))
如果您不想绑定任何值,可以使用do
:
(do (fun-call-1)
(fun-call-2)
(fun-call-3))
答案 1 :(得分:5)
我不是很有经验,但我会这样做:
(defn foo []
(procedure-with-side-effect)
(another-procedure-with-side-effect)
(let [value (procedure-that-creates-the-value)]
(do-something value)))
或
(defn foo []
(procedure-with-side-effect)
(another-procedure-with-side-effect)
(-> (procedure-that-creates-the-value)
do-something))
或
(defn foo []
(procedure-with-side-effect)
(another-procedure-with-side-effect)
(do-something (procedure-that-creates-the-value)))
编辑:defn
表达式包含隐式do
。
答案 2 :(得分:5)
在Lisp中,每个函数体都是一组有序的形式。将返回最后一个表单的值。如果过程不使用中间结果值作为参数,则不需要LET
。如果不需要通过命名变量来记录procedure-that-creates-the-value
,则不需要LET
绑定其值。
所以在Lisp中代码就是这样:
(defun foo ()
(procedure-with-side-effect)
(another-procedure-with-side-effect)
(do-something (procedure-that-creates-the-value)))