我最近一直在学习函数式编程(特别是Haskell,但我也学过关于Lisp和Erlang的教程)。虽然我发现这些概念非常有启发性,但我仍然看不到“无副作用”概念的实际一面。它的实际优势是什么?我试着用函数式思维来思考,但有些情况看起来过于复杂,没有能力以一种简单的方式保存状态(我不认为Haskell的monads“容易”)。
是否值得继续深入学习Haskell (或另一种纯函数式语言)?函数式或无状态编程实际上比过程性编程更有效率吗?我以后会继续使用Haskell或另一种函数式语言吗?或者我应该只为了理解而学习它?
我更关心的是工作效率,而不是性能。所以我主要问的是,在函数式语言中,我是否会比过程语言/面向对象语言/其他语言更有效率。
发布于 2009-05-10 02:20:28
阅读Functional Programming in a Nutshell。
无状态编程有很多优点,尤其是在多线程和并发代码方面。说白了,可变状态是多线程代码的敌人。如果值在默认情况下是不可变的,程序员就不需要担心一个线程会改变两个线程之间共享状态的值,所以它消除了一整类与竞争条件相关的多线程bug。因为没有竞争条件,所以也没有理由使用锁,所以不变性也消除了另一类与死锁相关的bug。
这就是函数式编程之所以重要的重要原因,也可能是跳上函数式编程列车的最好原因。还有许多其他的好处,包括简化的调试(即,函数是纯的,并且不会在应用程序的其他部分中改变状态),与严重依赖设计模式的语言相比,代码更简洁、更具表现力,样板代码更少,编译器可以更积极地优化代码。
发布于 2009-05-10 02:39:37
程序中无状态的部分越多,就有越多的方法可以在不破坏的情况下将这些部分组合在一起。无状态范例的力量不在于无状态(或纯洁性)本身,而在于它使您能够编写强大的、可重用的函数并将它们组合在一起。
你可以在John Hughes的论文Why Functional Programming Matters中找到一个很好的教程,里面有很多例子。
你将会更有效率,特别是如果你选择了一种同样具有代数数据类型和模式匹配的函数式语言(Caml,SML,Haskell)。
发布于 2009-05-10 04:14:48
许多其他的答案都集中在函数式编程的性能(并行性)方面,我认为这是非常重要的。但是,您确实特别询问了生产率,例如,在函数式范例中,您是否可以比在命令式范例中更快地编写相同的程序。
实际上,我发现(根据个人经验)用F#编程更符合我的思维方式,所以更容易。我认为这是最大的区别。我用F#和C#编写过程序,而且在我喜欢的F#中,“对抗语言”的情况要少得多。您不必考虑F#中的细节。这里有一些我发现我真的很喜欢的例子。
例如,即使F#是静态类型的(所有类型都是在编译时解析的),类型推断也会指出您的类型,所以您不必说出来。如果它不能解决这个问题,它会自动使你的函数/类/任何泛型。所以你永远不需要写任何泛型,它都是自动的。我发现这意味着我花了更多的时间思考这个问题,而不是如何实现它。事实上,每当我回到C#,我发现我真的很怀念这种类型推断,你永远不会意识到它有多让人分心,直到你不再需要做它。
同样在F#中,不是编写循环,而是调用函数。这是一个微妙的变化,但意义重大,因为您不必再考虑循环结构。例如,这里有一段代码,它将通过并匹配一些东西(我不记得是什么了,它来自一个项目Euler拼图):
let matchingFactors =
factors
|> Seq.filter (fun x -> largestPalindrome % x = 0)
|> Seq.map (fun x -> (x, largestPalindrome / x))我意识到,在C#中先做一个过滤器,然后再做一个映射(这是每个元素的转换)将会非常简单,但你必须在较低的层次上思考。特别是,您必须编写循环本身,并拥有自己的显式if语句,以及诸如此类的东西。自从学习了F#,我意识到我发现用函数式的方式编写代码变得更容易了,如果你想过滤,你可以写" filter ",如果你想映射,你可以写" map ",而不是实现每个细节。
我还喜欢|>运算符,我认为它将F#与ocaml分开,可能还有其他函数式语言。它是管道运算符,它允许您将一个表达式的输出“管道”到另一个表达式的输入。它让代码更多地遵循我的想法。就像上面的代码片段所说的,“获取因子序列,过滤它,然后映射它。”这是一种非常高层次的思考,在命令式编程语言中是得不到的,因为您正忙于编写循环和if语句。每当我使用另一种语言时,这是我最怀念的一件事。
因此,总的来说,尽管我可以用C#和F#编程,但我发现使用F#更容易,因为您可以从更高的层次思考。我会争辩说,因为函数式编程中删除了较小的细节(至少在F#中),所以我的工作效率更高。
编辑状态:我在其中一个注释中看到,您要求在函数式编程语言中提供一个“”示例。可以强制编写F#,因此这里有一个直接示例,说明如何在F#中使用可变状态:
let mutable x = 5
for i in 1..10 do
x <- x + ihttps://stackoverflow.com/questions/844536
复制相似问题