我的理解是,尾递归是递归,在这里,返回值对于完成操作是不必要的;也就是说,递归是函数的最后一步,函数的其余部分在进行递归调用后就完成了。
对此,我问这个例子(来自Norvig先生)是否是尾递归:
(defparameter *titles*
'(Mr Mrs Miss Ms Sir Madam Dr Admiral Major General)
"A list of titles that can appear at the start of a name.")
(defun first-name (name)
"Select the first name from a name represented as a list."
(if (member (first name) *titles*)
(first-name (rest name))
(first name)))一旦将最后的first-name作为if语句的分支调用,该函数就没有其他功能了;因此,它是尾递归吗?
发布于 2013-11-13 12:07:48
是的,这就是一个例子。
尾递归优化在Common的许多实现中都是可用的,但规范并不要求它。这意味着您可以在没有尾递归优化的情况下使用Common。
您还可能会发现,您所使用的版本需要稍微戳一下才能执行此优化。
因此,在某些实现中,您可能需要使用“声明”来通知编译器您希望优化速度。
(defun first-name (name)
"Select the first name from a name represented as a list."
(declare (optimize (speed 3) (compilation-speed 0) (debug 0) (safety 1)))
(if (member (first name) *titles*)
(first-name (rest name))
(first name)))编辑: 本站已经几岁了,但可能会提供一些信息。
同时,一定要阅读这些评论,因为约书亚和雷纳在这里对细节做了大量的改进。
发布于 2013-11-13 14:58:55
是也不是。通常是的。如果编译器支持TCO,并且正确的优化设置处于活动状态,也将对其进行优化。,但有时编译器无法优化它。
如果name被宣布为特殊,那么可能不会。
如果有类似的事情
(defvar name '(susanne mustermann))然后,函数的参数name将被声明为特殊(它将使用动态绑定)。然后编译器可能不会在first-name函数中使用尾调用优化。
这意味着您还需要知道变量符号是否声明为特殊符号。
这就是原因之一,应该像*name*那样编写全局特殊变量,以防止那些应该是词法变量的局部变量的特殊声明。在这种情况下,一项特别声明也会阻止TCO。
我们最好写:
(defvar *name* '(susanne mustermann))https://stackoverflow.com/questions/19953088
复制相似问题