用Clojure和Clojure为勇敢和真实的递归

时间:2017-10-12 21:17:54

标签: recursion clojure

我正在尝试学习使用 Clojure for the Brave and True (CFTBAT)这本书进行编程。在速成课程结束时,作者让我们编写一个小程序来说明Clojure中的循环。为了解释程序的循环和递归部分here,作者使用loop编写了一个较小的示例,然后显示可以用正常的函数定义替换loop

这是我无法理解的正常功能定义示例。这是代码:

(defn recursive-printer
    ([]
        (recursive-printer 0))
    ([iteration]
        (println iteration)
        (if (> iteration 3)
            (println "Bye!")
            (recursive-printer (inc iteration)))))

(recursive-printer)

我不理解代码,因为我看不到函数recursive-printer的参数在哪里。在Clojure中,函数的参数应该在括号中,而正文在括号中。因此,在此示例中,参数将是空参数[]iteration。但是,为什么他们也在括号之间?

什么是(recursive-printer 0)它是函数调用,函数调用自身吗?

如果有人能解释我这段代码是如何工作的,那将非常感激。

2 个答案:

答案 0 :(得分:2)

在clojure中,您可以定义一个函数,使其可以使用不同数量的函数 参数例如

(defn foo []
  ....)

是一个不带参数的函数。它就像这样......

(foo)

(defn foo [x]
  ...)

是一个带1个参数的函数。它可以被称为

(foo :a)

但有时,您可能想要定义一个取零或1的函数 论点。为此,您使用稍微不同的格式

(defn foo
  ([] ;no argument form 
    ...)
  ([x] ;single argument form
    ...))

一个常见的习惯用法是在递归函数定义中使用零参数形式 并包括一个“累加器”#39;论证形式作为主要部分 功能。所以,看看你的例子,你有

(defn recursive-printer
    ([] ; zero argument form
        (recursive-printer 0))
    ([iteration] ; 1 argument form
        (println iteration)
        (if (> iteration 3)
            (println "Bye!")
            (recursive-printer (inc iteration)))))

(recursive-printer)

当你调用(递归打印机)时,它会调用第一个表单(零参数 形成)。该形式又使用单个参数0调用该函数 调用第二种形式。

第二种形式首先打印出参数,然后测试是否存在 大于3,在第一次调用中它不是0,所以它执行 '否则'语句,使用新参数进行递归调用 当前参数增加1.现在您的参数为1并且打印出来 出。测试仍然是假的,因为1不是> 3,所以再次调用该函数 随着参数增加1,即2.在此调用中,打印2,测试为 仍然不比三个更大,所以用参数再次调用该函数 在此调用中,打印3并且测试仍然不是> 3。 3,所以 参数增加到4,函数再次调用4作为 论点。打印值4,但是此时间4> 3,所以字符串"再见"是 打印,因为这是终止条件,没有进一步的递归调用 制作并且堆栈展开并且函数终止。

答案 1 :(得分:1)

我们可以放弃零度:

(defn recursive-printer [iteration]
  (println iteration)
  (if (> iteration 3)
    (println "Bye!")
    (recursive-printer (inc iteration))))

...并使用显式0参数调用该函数:

(recursive-printer 0)
0
1
2
3
4
Bye!
=> nil

这让我们专注于递归。由于递归调用是最后一件事(在尾部位置),我们可以改为使用recur

(defn recursive-printer [iteration]
  (println iteration)
  (if (> iteration 3)
    (println "Bye!")
    (recur (inc iteration))))

......具有完全相同的效果。

我想,多余的东西会让事情变得混乱。