gpt4 book ai didi

coding-style - Common Lisp 递归辅助函数是否有样式约定?

转载 作者:太空宇宙 更新时间:2023-11-03 18:37:05 26 4
gpt4 key购买 nike

我想知道是否有由 ANSI 或实现作者或其他有影响力的权威发布的风格指南,用于使用递归辅助函数实现的 Lisp 函数,这些函数采用调用函数的人不需要的附加参数想一下。这是我能想到的最简单的例子。这三者中的哪一个(如果有的话)在 common lisp 的标准化风格指南中是首选(如果有的话)?

(defun factorial (n)
(defun tail-factorial (n m)
(if (= n 1)
m
(tail-factorial (- n 1) (* n m))))
(tail-factorial n 1))

这看起来很不愉快,因为函数声明中包含函数声明。我会使用 lambda 来避免命名辅助函数和复杂的事情,但我不清楚如何通过调用自身来在 lambda 表达式中递归。即使有办法让匿名函数调用自身,它似乎也会变得困惑,特别是如果需要帮助者需要帮助者......

另一种选择是首先(或之后,但这会让 sbcl 提示)声明 tail guy:

(defun tail-factorial (n m)
(if (= n 1)
n
(tail-factorial (- n 1) (* n m))))
(defun factorial (n)
(tail-factorial n 1))

这看起来很不愉快,因为阅读我的代码的人会看到尾阶乘,并且可能会觉得有必要了解它,即使它只是阶乘的辅助函数,不会在其他地方使用。在我自己的代码中,我一直在编写与此类似的函数,我真的很难提出评论,让我重新理解我在几个月或几年后所做的事情。同样,当帮助者需要帮助者需要帮助时,情况会变得非常糟糕......

另一种选择是使用可选值:

(defun factorial (n &optional (m 1))
(if (= n 1)
m
(factorial (- n 1) (* n m))))

这看起来很不愉快,因为我们只希望有一个阶乘参数。这个函数之外的任何人都没有理由用第二个参数调用它。我发现尝试理解带有我永远不会使用的可选参数的代码很烦人。

现在,我很清楚问你认为什么是最好的是 stackoverflow 不喜欢的那种主观对话,所以我的客观问题是是否有某种标准化的风格指南来说明这些备选方案中的哪一个是首选。我使用 SBCL,但没有在他们的网站上找到此类指南,而且我不知道 ANSI 或任何其他标准化机构(包括其他实现者)发布了此类指南。

也许还有另一种选择,我欢迎您提出建议。我一直遇到这种需要一点辅助功能的情况(谁需要辅助功能等),我想习惯以大多数人会清楚的方式写作。有人在 Recursing in a lambda function 上问过类似的问题,并且有几个人推荐了一些最喜欢的宠物项目,但没有人提到风格指南。

提前致谢!

最佳答案

defun 只生成全局函数。如果您在 defun 中使用 defun ,您实际上是在每次调用它时创建一个新的全局函数。要使局部词法函数仅在 factorial 中使用,标准方法是使用 labels

(defun factorial (n)
(labels ((tail-factorial (n m)
(if (= n 1)
m
(tail-factorial (- n 1) (* n m)))))
(tail-factorial n 1)))

Common Lisp 无法保证进行尾调用优化,因此这可能会破坏堆栈。对于严肃的工作,您会使用 loop 宏来执行此操作。

可选参数有效,但如果用户无意提供它,则您真的不应该将内部参数设为可选。然后它只是泄漏抽象并制作困惑的文档。

关于coding-style - Common Lisp 递归辅助函数是否有样式约定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30178852/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com