【问题标题】:Side effects in Lisp/ClojureLisp/Clojure 中的副作用
【发布时间】:2014-03-07 04:36:16
【问题描述】:

我的问题是关于构建具有副作用的 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 块看起来很可怕。有没有更好的方法来做到这一点?

【问题讨论】:

    标签: clojure lisp


    【解决方案1】:

    如果你不需要函数调用的中间值,你可以在defn的body里面放一堆函数调用:

    (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))
    

    【讨论】:

      【解决方案2】:

      在 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)))
      

      【讨论】:

        【解决方案3】:

        我不是很有经验,但我会这样做:

        (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 包装。

        【讨论】:

          猜你喜欢
          • 2014-03-29
          • 2015-11-01
          • 1970-01-01
          • 2011-10-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-25
          • 2015-06-04
          相关资源
          最近更新 更多