【发布时间】:2013-11-01 08:03:45
【问题描述】:
我曾经像这样在 Haskell 中编写嵌套辅助函数(顺便说一句,偶尔使用外部函数的参数并且是递归的)(loop):
sum a b = let
loop s i = if i > b then s else loop (s + i) (i + 1)
in loop 0 a
Common Lisp 中最清晰的类比是什么?
我在这里四处搜索,发现一些讨论集中在从函数返回函数(以及尝试调用此类“返回”函数时可能出现的问题),据我所知,情况并不完全相同。
【问题讨论】:
-
虽然帮助函数在 Lisp 中很常见,但不鼓励以这种方式进行迭代。 Google coding standards tell you to prefer iteration over recursion。这当然不是您问题的答案,但我认为无论如何它可能会有用。
-
@wvxvw,在这种情况下使用 Haskell 的递归似乎是在尾部位置,就像在尾部位置调用名称时,Scheme 命名为
let一样。它最终成为首选或尾随,例如变相迭代。需要注意的是,Common Lisp 不保证尾调用,因此需要明确使用迭代方法来避免堆栈溢出。 -
@PauloMadeira 好吧,OP 用 Common Lisp 编写。这绝对不是您在 CL 中迭代的方式。在旁注中,我认为答案中的 Lisp 代码下意识地修复了它:OP 可能意味着
... then s else loop ...而不是... then sum else loop ...。 OP 的版本无法在 Haskell 中编译。 GHC 会将此理解为无限类型。 -
@wvxvw 感谢您的 cmets!作为一个 CL 菜鸟,我非常感谢他们。我对选择尾递归的解释……嗯,说来话长。我们实际上在研究函数式编程的原理。在我大学的 Lisp 上。我担任助教,而 Lisp 是由讲师选择的。 (我更喜欢 Haskell。)我使用 Touretzky 的关于 Lisp 的书,他也给出了 DO-stuff 之前的递归示例。
-
是的,出于某种原因,坚持认为 CL 是一种函数式语言,或者说它是学习 FP 的良好候选者是很常见的(嗯,在某种“常见”意义上)。我不是 FP 的忠实粉丝,尤其不是 Haskell :) 但 CL 不是一个好的选择/对于 FP 来说非常不习惯。有一些库可以使 CL 中的函数式编程更容易接受(函数式容器、用于常见习语的辅助函数,例如组合、柯里化等),但它们的存在归功于上述混淆的事实。 CL 是关于编程舒适度、元编程和研究的。
标签: common-lisp nested-function