Functional programming 函数式编程的陷阱/缺点
什么时候您不想使用函数式编程?它不擅长什么 我更多的是寻找范式作为一个整体的缺点,而不是像“没有广泛使用”或“没有好的调试器可用”这样的东西。到目前为止,这些答案可能是正确的,但它们涉及到FP是一个新概念(一个不可避免的问题),而不是任何固有的特性 相关的:Functional programming 函数式编程的陷阱/缺点,functional-programming,paradigms,Functional Programming,Paradigms,什么时候您不想使用函数式编程?它不擅长什么 我更多的是寻找范式作为一个整体的缺点,而不是像“没有广泛使用”或“没有好的调试器可用”这样的东西。到目前为止,这些答案可能是正确的,但它们涉及到FP是一个新概念(一个不可避免的问题),而不是任何固有的特性 相关的: 如果您的语言没有提供良好的机制通过您的程序检查状态/异常行为(例如,一元绑定的语法糖),那么任何涉及状态/异常的任务都将成为一件麻烦事。(即使有了这些糖类,有些人可能会发现在FP中处理状态/异常会更加困难。) 函数式习惯用法通常会产生
函数式习惯用法通常会产生很多控制反转或惰性,这通常会对调试(使用调试器)产生负面影响。(这在一定程度上被FP的不易出错性所抵消,因为FP具有不变性/引用透明性,这意味着您需要更少的调试次数。)以下是我遇到的一些问题:
除了速度或采用问题以及解决一个更基本的问题之外,我听说通过函数式编程,为现有数据类型添加新函数非常容易,但添加新数据类型“很难”。考虑: (用SMLnj书写。另外,请原谅这个有点做作的例子。) 我可以很快添加以下内容:
fun angryNoise(Dog) = "grrrrrr"
| angryNoise(Cat) = "hisssss";
但是,如果我向Animal添加了一个新类型,我必须通过每个函数来添加对它的支持:
datatype Animal = Dog | Cat | Chicken;
fun happyNoise(Dog) = "pant pant"
| happyNoise(Cat) = "purrrr"
| happyNoise(Chicken) = "cluck cluck";
fun excitedNoise(Dog) = "bark!"
| excitedNoise(Cat) = "meow!"
| excitedNoise(Chicken) = "cock-a-doodle-doo!";
fun angryNoise(Dog) = "grrrrrr"
| angryNoise(Cat) = "hisssss"
| angryNoise(Chicken) = "squaaaawk!";
但是请注意,面向对象语言的情况正好相反。向抽象类中添加一个新的子类非常容易,但如果您想向抽象类/接口中添加一个新的抽象方法以供所有子类实现,则可能会非常繁琐。函数式编程的一个大缺点是,在理论层面上,它与硬件以及大多数命令式语言不匹配。(这是其明显优势之一的另一面,能够表达你想做什么,而不是你想让计算机如何做。) 例如,函数式编程大量使用递归。这在纯lambda演算中很好,因为数学的“堆栈”是无限的。当然,在真正的硬件上,堆栈是非常有限的。在大数据集上天真地递归会使程序变得繁荣。大多数函数式语言都会优化尾部递归,这样就不会发生这种情况,但使算法尾部递归可能会迫使您执行一些相当不实用的代码练习(例如,尾部递归映射函数创建一个向后列表或必须建立一个差异列表,因此与非尾部递归版本相比,它必须做额外的工作才能以正确的顺序返回正常映射列表)
(感谢贾里德·厄普代克(Jared Updike)提出的差异列表建议。)菲利普·瓦德勒(Philip Wadler)就此写了一篇论文(名为《为什么没有人使用函数式编程语言》),并指出了阻止人们使用FP语言的实际陷阱:
foldl
,并为此实现了foldr
。这两个函数的实现有很大不同。有一个fold的替代实现l
,称为foldl'
。除此之外,还有一个版本的语法稍有不同,分别称为foldr1
和foldl1
,初始值不同。其中有一个foldl1'
对应的foldl1
实现。折叠的函数似乎所有这一切都不令人兴奋[lr].
require作为参数并在归约中内部使用有两个独立的签名,只有一个变量在无限列表(r)上工作,并且只有一个变量在常量内存中执行(正如我所理解的(L),因为它只需要redex
).要理解为什么foldr
可以在无限列表上工作,至少需要对语言lazy behavoir有一个良好的理解,以及不是所有函数都会强制计算第二个参数的小细节。这些函数的在线图表对于大学里从未见过它们的人来说非常混乱。没有perldoc
等效。我找不到Haskell prelude中任何函数的单一描述。prelude是一种预装了core的发行版。我最好的资源是一个我从未见过的家伙(Cale),他在自己的时间里花费了巨大的代价帮助我
哦,折叠不一定是r
datatype Animal = Dog | Cat | Chicken;
fun happyNoise(Dog) = "pant pant"
| happyNoise(Cat) = "purrrr"
| happyNoise(Chicken) = "cluck cluck";
fun excitedNoise(Dog) = "bark!"
| excitedNoise(Cat) = "meow!"
| excitedNoise(Chicken) = "cock-a-doodle-doo!";
fun angryNoise(Dog) = "grrrrrr"
| angryNoise(Cat) = "hisssss"
| angryNoise(Chicken) = "squaaaawk!";