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