GISC 练习 8.24 和 8.26:cond 结果形式的 if-condition 未按预期工作

GISC exercise 8.24 and 8.26: if-condition in result-form of cond not working as expected

David Touretzky 的“符号计算简介”练习 8.24 和 8.26 状态:

8.24: 编写 COUNT-DOWN,一个使用 list-consing 递归从 n 开始倒数的函数。 (计数 5)应该产生列表(5 4 3 2 1)。

8.26:假设我们要修改 COUNT-DOWN 以便列表 构造以零结尾。例如,(COUNT-DOWN 5) 会产生 (5 4 3 2 1 0)。 [...]

所以我尝试将这两个练习组合成一个函数 countdown,它接受关键字参数 incl-zero,如下所示:

(defun countdown (n &key (incl-zero nil))
  (cond
    ((zerop n) (if incl-zero '(0) nil))
    (t (cons n (countdown (1- n))))))

(countdown 5)
(countdown 5 :incl-zero t)

然而,两次调用倒计时 return (5 4 3 2 1),所以似乎 :incl-zero t 没有达到 if 条件。为什么会这样?

我的天啊,我觉得我很愚蠢。

(defun countdown (n &key (incl-zero nil))
  (cond
    ((zerop n) (if incl-zero '(0) nil))
    (t (cons n (countdown (1- n) :incl-zero incl-zero)))))

(countdown 5)
(countdown 5 :incl-zero t)

我猜是递归模因的牺牲品..

您注意到了该错误,但请注意,当您的参数不会从一个调用更改为另一个调用时,您可能应该定义一个局部递归函数以仅传递 do 改变。这更容易编写和理解。此外,传递关键字参数可能会带来一些运行时开销。

(defun countdown (n &key (incl-zero nil))
  (labels ((recurse (n)
             (cond
               ((zerop n) (if incl-zero '(0) nil))
               (t (cons n (recurse (1- n)))))))
    (recurse n)))