减少或显式递归?

Wan*_*ang 12 lisp coding-style

我最近开始和朋友一起阅读Paul Graham的On Lisp,我们意识到我们对reduce有不同的看法:我认为它非常清晰简洁地表达了某种递归形式; 他更喜欢非常明确地写出递归.

我怀疑我们在某些情况下是正确的而在另一种情况下是错误的,但我们不知道这条线在哪里.你何时选择一种形式而不是另一种形式,在做出这种选择时你会怎么想?

为了清楚我对reduce和显式递归的意思,这里实现了两次相同的函数:

(defun my-remove-if (pred lst)
    (fold (lambda (left right)
                  (if (funcall pred left) 
                      right 
                      (cons left right)))
          lst :from-end t))

(defun my-remove-if (pred lst)
    (if lst
        (if (funcall pred (car lst))
            (my-remove-if pred (cdr lst))
            (cons (car lst) (my-remove-if pred (cdr lst))))
        '()))
Run Code Online (Sandbox Code Playgroud)

我害怕我开始使用Schemer(现在我们是Racketeers?)所以如果我搞砸了Common Lisp语法,请告诉我.希望即使代码不正确,这一点也很明确.

Ira*_*ter 11

如果您有选择,您应该始终以最抽象的术语表达您的计算意图.这使读者更容易理解您的意图,并使编译器更容易优化您的代码.在您的示例中,当编译器通过命名它而非常简单地知道您正在执行折叠操作时,它也很容易知道它可能并行化叶操作.当编写极低级别的操作时,编译器很难弄清楚这一点.

  • @huayuan:不,我的意思是"最抽象".折叠比一堆详细的手工编码递归代码更抽象. (7认同)
  • 三态,七个符号图灵机比递归更通用,但我不建议用一个编码.您不希望您的读者或您的编译器猜测您正在做什么,因为它必须推断所有这些低级别细节正在尝试完成的事情(例如,图灵机中的磁带正在做什么)."抽象"意味着"更少细节".纯粹的递归版本有太多的细节; 它告诉你如何完成计算,到达折叠的特定实现. (6认同)
  • 这是"最不抽象"的错字吗?写作的其余部分似乎暗示你认为更具体(即,不那么一般/抽象)更好. (2认同)