Lisp / Clojure中的副作用

时间:2014-03-07 04:36:16

标签: clojure lisp

我的问题是关于构造带有副作用的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块看起来很可怕。有更好的方法吗?

3 个答案:

答案 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)))