Recursion 计划/骗局新手:大量使用递归是一种生活方式还是我只是在经历一个典型的阶段

Recursion 计划/骗局新手:大量使用递归是一种生活方式还是我只是在经历一个典型的阶段,recursion,scheme,racket,Recursion,Scheme,Racket,在过去的几个月里,从F#到Haskell再到Scheme(Racket),我一直在研究函数语言。我从来没有真正使用过递归,但Haskell及其模式匹配确实帮助我减少了对它们的恐惧。现在我使用Scheme,似乎默认使用递归方法。我很好奇,这是否意味着刚刚经历了一个“ooo闪亮”阶段,或者递归是否是方案开发的主要部分 旁注:每当我编写递归方法时,我一直在寻找尾部递归。每个方法都有一点。递归通常是Lisp的主要功能(不仅仅是Scheme)。然而,更高级的用户经常更多地使用其他控制流原语(尽管它们可能反

在过去的几个月里,从F#到Haskell再到Scheme(Racket),我一直在研究函数语言。我从来没有真正使用过递归,但Haskell及其模式匹配确实帮助我减少了对它们的恐惧。现在我使用Scheme,似乎默认使用递归方法。我很好奇,这是否意味着刚刚经历了一个“ooo闪亮”阶段,或者递归是否是方案开发的主要部分


旁注:每当我编写递归方法时,我一直在寻找尾部递归。

每个方法都有一点。递归通常是Lisp的主要功能(不仅仅是Scheme)。然而,更高级的用户经常更多地使用其他控制流原语(尽管它们可能反过来以递归方式实现)。

不,这不是一个阶段,而是一个主要阶段。递归是一种技术,它允许您解决比其他方法更复杂的问题,即使在需要迭代解决方案的情况下,如果您首先制定一个递归解决方案,也更容易实现

掌握递归也为您打开了新的问题领域。典型的仅迭代程序员无法处理涉及在正式语言之间进行操作和翻译的问题,例如,根据用户希望看到的报告的编码描述编写复杂的SQL查询生成器


如果您想继续前进,您应该研究如何更好地使用fold,它通过将计算的递归结构与递归步骤的内容分离,从而从显式递归中抽象出来。因此,例如Scheme的右折叠可以被视为“执行与此列表形状相同的递归计算,将空列表映射到此值作为基本情况,每个cons都映射到此函数。”然后在另一个上进行折叠,更复杂的数据结构。

我认为这取决于您所谈论的递归类型

第一件让人大开眼界的事(例如,如果您正在处理SICP),就是迭代可以被递归所取代。您在过去的生活中编写的所有这些冗长且容易出错的循环代码都可以用另一种方式完成。这是一个很酷的体验(正如你所说的)“哦,闪亮!”

下一个让人大开眼界的问题是,在现实生活中,实际编写的递归代码是多么少。相反,通过使用诸如
map
fold
之类的构建块,可以避免繁琐的迭代和递归

此外,在Racket中,你可能会从
map
fold
毕业,而更喜欢像
for/list
for/vector
for/fold
这样的“理解”,它们不仅适用于列表,还适用于序列。在食物链的上游,你继续前进

话虽如此,有些问题最好是递归解决(而不仅仅是“通过其他方式迭代”)。我认为,你在《第一款大开眼界》中获得的舒适度将有助于实现这一目标。

+1学习使用——并最终实现自己的——高阶函数绝对是你应该采取的下一个“哦,闪亮!”步骤。在那之后,也许是单子和箭。