迭代过程与递归过程

时间:2018-09-05 09:43:25

标签: recursion clojure tail-recursion sicp

通读SICP Distilled,并尝试围绕迭代和递归过程。给出的示例是:

(defn + [a b]
  (if (= a 0) b (inc (+ (dec a) b))))

(defn + [a b]
  (if (= a 0) b (+ (dec a) (inc b))))

其中一个是迭代过程(状态完全由一个迭代函数的参数维护),另一个是递归过程(在等待上一个函数调用完成时,状态必须保留在“幕后”)

我的猜测在这里是第二个是迭代的,因为可以在将参数应用于函数之前先对参数求值,而前者必须保留连续的函数调用堆栈,等待最后的+操作完成,然后才能展开堆栈,并在每一步运行inc

1 个答案:

答案 0 :(得分:12)

有一种简单的方法可以将迭代过程与递归过程区分开,问问自己:在递归调用之后 还有什么要做的吗?如果答案是肯定的,那么这是一个递归过程,这就是这里发生的事情:

<?php

require_once dirname(__DIR__, 1).'/Config.php';

if(isset($_POST['action']) && $_POST['action'] === 'savePost'){

  $clientName = $_POST['client_name'];
  $postContent = $_POST['post_content'];

  $stmt = $db->prepare("INSERT INTO portfolio (post_content, client_name) VALUES (?, ?)");
  if($stmt->execute(array($postContent, $clientName))){
    echo 'ok';
  } else {
    echo $db->errorCode();
  }

}

?>

如果答案是否定的,那么这是一个反复的过程,这是在这里发生的事情:

case class Color(name: String) {
  val code: Int = ...
}

在第二种情况下,我们说case class Color(name: String) { def code: Int = ... } 处于尾部位置,并且支持它的解释器将对其进行优化,请参见:tail call。除非您使用recur,否则Clojure不能进行尾部呼叫优化。