Common lisp GISC练习8.24和8.26:如果cond结果表中的条件未按预期工作
David Touretzky的《符号计算状态温和介绍》练习8.24和8.26: 8.24:写倒计时,一种使用考虑递归的列表从n开始倒计时的函数。计数5应生成列表5 4 3 2 1 8.26:假设我们想要修改倒计时,以便列表可以 构造以零结尾。例如,倒计时5将产生543200。[……] 因此,我尝试将这两个练习组合成一个函数倒计时,该函数采用包含零的关键字参数,如下所示:Common lisp GISC练习8.24和8.26:如果cond结果表中的条件未按预期工作,common-lisp,Common Lisp,David Touretzky的《符号计算状态温和介绍》练习8.24和8.26: 8.24:写倒计时,一种使用考虑递归的列表从n开始倒计时的函数。计数5应生成列表5 4 3 2 1 8.26:假设我们想要修改倒计时,以便列表可以 构造以零结尾。例如,倒计时5将产生543200。[……] 因此,我尝试将这两个练习组合成一个函数倒计时,该函数采用包含零的关键字参数,如下所示: (defun countdown (n &key (incl-zero nil)) (cond ((ze
(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)
但是,两个倒计时调用都返回54321,因此看起来:inclzero 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)
我想我成了递归迷因的牺牲品..天哪,我觉得自己很愚蠢
(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)
我猜是递归迷因的牺牲品。您注意到了错误,但请注意,当您的参数从一个调用变为另一个调用时,您可能应该定义一个局部递归函数,只传递确实发生变化的参数。这更容易书写和理解。此外,传递关键字参数可能会带来一点运行时开销
(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)))
您注意到了错误,但请注意,当您的参数在一个调用到另一个调用时没有变化时,您可能应该定义一个局部递归函数,以便只传递变化的参数。这更容易书写和理解。此外,传递关键字参数可能会带来一点运行时开销
(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)))