Loops 递归有什么用处吗?

Loops 递归有什么用处吗?,loops,recursion,tail-recursion,Loops,Recursion,Tail Recursion,我最近学习了尾部递归,这是一种在给定太大的数字时不会崩溃的递归方法。我意识到我可以很容易地将尾部递归重写为while循环,并让它做基本上完全相同的事情,这让我想知道——当你可以用普通循环做任何事情时,递归有什么用处吗 是的,递归代码看起来更小,更容易理解,但它也有可能完全崩溃,而简单的循环无法在执行相同任务时崩溃。我举个例子,它纯粹是功能性的: Haskell中的每个函数都是数学意义上的函数 i、 例如,纯的。即使是有副作用的IO操作也只是一个问题 描述要做什么,由纯代码生成。没有 语句或指令,

我最近学习了尾部递归,这是一种在给定太大的数字时不会崩溃的递归方法。我意识到我可以很容易地将尾部递归重写为while循环,并让它做基本上完全相同的事情,这让我想知道——当你可以用普通循环做任何事情时,递归有什么用处吗

是的,递归代码看起来更小,更容易理解,但它也有可能完全崩溃,而简单的循环无法在执行相同任务时崩溃。

我举个例子,它纯粹是功能性的:

Haskell中的每个函数都是数学意义上的函数 i、 例如,纯的。即使是有副作用的IO操作也只是一个问题 描述要做什么,由纯代码生成。没有 语句或指令,仅限不能变异的表达式 局部或全局变量或访问状态,如时间或随机变量 数字

因此,在haskell中,如果 递归调用是函数本身的最终结果。如果 递归调用的结果必须进一步处理,例如,添加 1到它,或者将另一个元素考虑到它的开头,它是 不是尾部递归


另一方面,在许多编程语言中,调用函数会占用堆栈空间,因此尾部递归的函数可能会构建大量对自身的调用堆栈,这会浪费内存。因为在尾部调用中,包含函数即将返回,所以实际上可以丢弃它的环境,并且可以在不创建新堆栈框架的情况下进入递归调用。这个技巧被称为尾部调用消除或尾部调用优化,允许尾部递归函数无限期地重复出现。

我已经很久没有发布这个问题了,我对这个主题的看法已经改变。原因如下:

我学习了Haskell,它是一种修复递归所有不好的地方的语言——递归定义和算法被转换成普通的循环算法,大多数时候你甚至不直接使用递归,而是使用map、fold、filter或它们的组合。当所有不好的东西都被去除后,函数式编程的好的一面开始显露出来——所有东西都更接近它的数学定义,而不是被笨重的循环和变量所掩盖


对于正在努力理解递归为何伟大的其他人,请学习Haskell。它还有很多其他非常有趣的特性,比如,惰性值只有在被请求时才会被计算,静态变量永远不能被修改,纯函数除了获取输入和返回输出之外不能做任何事情,因此不需要打印到控制台,强类型的类型系统非常有表现力,充满了令人兴奋的抽象概念,如函子、单子、状态等等。我几乎可以说这改变了我的生活。

没有关于这个问题的新信息。我目前正在学习lisp,它有标准循环和尾部递归优化。我试图找到一个使用尾部递归的理由,当一个普通的循环在没有声明函数的情况下执行完全相同的任务时。你有没有尝试过使用循环来解决河内塔的问题?这是一个很棒的例子@Nykros,从很多方面来说,阅读和理解尾部递归要简单得多,有时速度更快,这可能是因为对压力。。。不是每个人都像@umnikosin Common Lisp那样看待天才的想法。没有保证,递归的使用是不受欢迎的;在可能的情况下,最好使用。re Towers of Hanoi,如果很难使用循环,那么使用尾部递归也同样困难。欢迎使用StackOverflow。请阅读并遵循帮助文档中的发布指南。在这里申请。这个问题已经有很多关于堆栈溢出和Internet的答案了。循环有什么用处吗?递归可以做循环所能做的一切。一个简单的循环可能会因索引越界或整数溢出而崩溃,但是你知道,程序员不应该负责确保他们的代码不会崩溃@普伦姆,我一个也没找到helpful@MrZander递归也有这两个问题:虽然我想有不止一种方法可以做完全相同的事情……也许这个问题应该转到meta so