首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这个lisp示例是否带有尾递归?

这个lisp示例是否带有尾递归?
EN

Stack Overflow用户
提问于 2013-11-13 11:52:28
回答 2查看 1.5K关注 0票数 1

我的理解是,尾递归是递归,在这里,返回值对于完成操作是不必要的;也就是说,递归是函数的最后一步,函数的其余部分在进行递归调用后就完成了。

对此,我问这个例子(来自Norvig先生)是否是尾递归:

代码语言:javascript
复制
(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语句的分支调用,该函数就没有其他功能了;因此,它是尾递归吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-13 12:07:48

是的,这就是一个例子。

尾递归优化在Common的许多实现中都是可用的,但规范并不要求它。这意味着您可以在没有尾递归优化的情况下使用Common。

您还可能会发现,您所使用的版本需要稍微戳一下才能执行此优化。

因此,在某些实现中,您可能需要使用“声明”来通知编译器您希望优化速度。

代码语言:javascript
复制
(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)))

编辑: 本站已经几岁了,但可能会提供一些信息。

同时,一定要阅读这些评论,因为约书亚和雷纳在这里对细节做了大量的改进。

票数 2
EN

Stack Overflow用户

发布于 2013-11-13 14:58:55

是也不是。通常是的。如果编译器支持TCO,并且正确的优化设置处于活动状态,也将对其进行优化。,但有时编译器无法优化它。

如果name被宣布为特殊,那么可能不会。

如果有类似的事情

代码语言:javascript
复制
(defvar name '(susanne mustermann))

然后,函数的参数name将被声明为特殊(它将使用动态绑定)。然后编译器可能不会在first-name函数中使用尾调用优化。

这意味着您还需要知道变量符号是否声明为特殊符号。

这就是原因之一,应该像*name*那样编写全局特殊变量,以防止那些应该是词法变量的局部变量的特殊声明。在这种情况下,一项特别声明也会阻止TCO。

我们最好写:

代码语言:javascript
复制
(defvar *name* '(susanne mustermann))
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19953088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档