最近,对于Scala,Clojure和F#,我已经听到了很多有关函数式编程语言的热情。我最近开始学习Haskell,以学习FP范例。
我喜欢它,它真的很有趣,并且适合我的数学背景。
但这真的有关系吗?显然,这并不是一个新主意。
这是我的问题:
- 是什么促成了最近FP的热情?是对OO仅仅是无聊,还是为了使FP比以前更需要而进行了一些更改?
- 这是否预示着FP的未来?还是像对象数据库这样的时尚?
换句话说,任何人都可以帮助我了解它的来历和去向吗?
最近,对于Scala,Clojure和F#,我已经听到了很多有关函数式编程语言的热情。我最近开始学习Haskell,以学习FP范例。
我喜欢它,它真的很有趣,并且适合我的数学背景。
但这真的有关系吗?显然,这并不是一个新主意。
这是我的问题:
换句话说,任何人都可以帮助我了解它的来历和去向吗?
Answers:
导致“兴趣爆炸”的FP的主要创新之一是monads。
1992年1月,Philip Wadler撰写了一篇名为《函数式编程的本质》的论文,该论文将monads引入函数式编程中,作为处理IO的一种方式。
纯的,惰性的,功能性编程语言的主要问题是处理IO的实用性。它是程序设计中“笨拙小队”的成员之一,因为“从实用的角度来看,懒惰和副作用是不兼容的。如果要使用惰性语言,它几乎必须是一种纯粹的功能性语言。如果要使用副作用,最好使用严格的语言。” 参考
在monads之前的IO问题是,对于实际上对任何事情都有用的程序,保持纯度是不可能的。所谓IO,是指处理状态变化的任何事物,包括从用户或环境获取输入和输出。在纯函数式编程中,所有内容都是不可变的,以实现惰性和纯净(无副作用)。
monads如何解决IO问题?好吧,无需过多讨论monad,他们基本上将“ World”(运行时环境)作为monad的输入,并产生一个新的“ World”作为输出,其结果是:IO a = World->(a,世界)。
因此,FP已进入越来越多的主流,因为最大的问题IO(及其他)已经解决。众所周知,已经集成到现有的OO语言中。例如,LINQ就是单子。
有关更多信息,建议阅读有关我的答案中引用的monad和论文。
type IO a = UI -> (a, UI)
一个绝妙的答案。
对传统语言(如C,Java,C#,汇编器等)进行编程时的主要问题之一是,为了完成给定的任务,您必须采取一系列尴尬的步骤,因为您需要先准备所有依赖项,然后再准备。较早的依赖
例如:为了执行A,您必须有B和C,并且B取决于D和E,结果是
因为您必须先准备好成分,然后才能使用它们。
函数式语言,尤其是惰性语言,使这一语言颠倒了。通过让A说它需要B和C,并让语言运行时弄清楚何时获取B和C(这又需要D和E),所有这些都在需要评估A时进行评估,因此您可以创建非常简洁的代码构建块,从而导致程序精简。惰性语言还允许使用无限列表,因为仅计算实际使用的元素,而无需在能够使用整个数据结构之前将其存储在内存中。
真正的妙招是,这种自动的“哦,我需要一个B和C”机制是可扩展的,因为对执行该评估的位置和时间没有任何限制(如在顺序程序中一样),因此可以在甚至在不同的处理器或计算机上。
这就是功能语言之所以有趣的原因-因为“运行时做什么”机制由运行时系统接管,而不是程序员必须手动进行。这与从Java到C的自动垃圾回收一样重要,这是一个主要差异,这也是为什么用Java编写比C编写健壮的,可扩展的多线程软件要容易得多的主要原因之一。功能语言中的可扩展多线程软件...
在80年代末/ 90年代初,计算机变得足够强大,可以用于Smalltalk风格的OOP。如今,计算机对于FP而言已经足够强大。FP是在更高层次上进行编程的,因此,尽管编程更愉快,但不是最有效的方法确实可以解决某个问题。但是计算机是如此之快,以至于您不在乎。
使用纯功能编程语言可以更轻松地进行多核编程,因为您必须隔离状态改变代码。
今天,编程语言的边界也变得模糊。如果您想使用另一种范例,则不必放弃一种范例。您可以使用大多数流行语言进行FP,因此入门门槛很低。
如今需要分布式计算。
FP使用功能作为没有状态的构建块,因此 ,使用相同参数调用n次的功能应始终返回相同的值,并且不会产生副作用。
因此,您可以将相同的功能发送到一堆机器上,以并行执行工作。
在OO范式中,这有点困难,因为构造块是对象,根据定义,它们几乎是有状态的。如果多次调用相同的方法,则在同步内部数据时必须小心,以避免数据损坏。尽管仍然可能,但是在某些必须分配计算的情况下,FP范例比OO更好。
FP(某种程度上是NoSQL)的出现是在数十万台并行计算机上实现惊人的计算结果的故事之后的,并且它是多么容易。
但这可能只是需要这种设置的应用程序的一种小众市场。对于许多其他应用程序/系统,过程和OO都可以正常工作。
因此,所有这些都将扩大我们的编程视野,并重新采用我们曾经认为不会超出学术界的这些概念。
几年前,我学会了用Lisp编程,那时,我什至不知道那是FP。到现在为止,我几乎已经忘记了有关它的所有内容,但是可以肯定地帮助我很容易地理解诸如递归的概念。
我认为该问题的主要答案是“暴露”。
函数式编程并不是什么新鲜事物,大约12年前,我在大学里曾教过Haskell,并且喜欢它。但是在我的专业工作中很少使用这种语言。
最近,主流语言中已经有许多使用多范式方法的语言受到关注。F#,JavaScript是最好的例子。
特别是JavaScript,特别是与功能样式的框架语言(如jQuery或Prototype)一起使用时,由于动态现代网站上的所有工作,JavaScript 已成为许多人的日常语言。这种对功能风格的了解使人们意识到了它所赋予的力量,尤其是当人们能够随意退回到命令式风格时。
一旦人们接触了它们,他们就会尝试功能语言的更为完善的变体,并开始将其用于日常任务。
随着F#在Visual Studio 2010中成为一门一流的语言,而jQuery(et al)变得如此重要,使用这些语言变得越来越现实,而不是仅仅使用晦涩难懂的程序或制作独立的程序。
请记住,代码必须是可维护的-一定数量的开发人员必须使用和支持语言,以使公司在使用它们时感到安全。
在演讲中,安德斯·海斯伯格(Anders Hejlsberg)解释了他对该主题的看法。
[编辑]
抱歉,链接错误。现在它指向正确的位置。
一小时通话的一些要点的简短摘要:
功能语言比程序语言允许使用更具声明性的编程风格,因此用FL编写的程序通常更专注于what而不是how。由于FL具有优雅的数学结构,因此它们也更易于通过编译器进行优化和转换,这也使元编程和嵌入式DSL的构建变得容易。所有这些加在一起使功能性程序比程序性程序更简洁,更易于记录文档。
同样,面对不久的将来的多核时代,编程语言需要能够以不同的方式利用多线程/处理。单核计算机上的多线程实际上是一种时间共享机制,而系统的体系结构反映了这一点。manycore机器上的多线程将大不相同。函数语言特别适合于并行化,因为它们大多数情况下会避免状态,因此不必担心共享可变数据的完整性(因为往往没有共享可变数据)。
我认为这与功能编程范例和Web编程之间的紧密关联有关。
Ruby on Rails为整个功能编程方法带来了极大的缓解,因为它提供了快速访问功能性(heh heh)Web应用程序的途径。关于此,有一个有趣的讨论,一个特别的答案很突出:
函数式编程非常适合Web应用程序。该Web应用程序接收HTTP请求并产生HTML结果。这可以被认为是从请求到页面的功能。
与台式机应用程序相比,台式机应用程序通常需要长时间运行,有状态的UI和多个方向的数据流。这更适用于OO,它关注具有状态和消息传递的对象。
鉴于函数式编程已经存在了很长时间,我想知道为什么我没有看到很多招聘广告为Lisp开发人员开发未开发的Web项目。
这是我的问题:1.是什么导致了最近的FP热情?是对OO仅仅是无聊,还是为了使FP比以前更需要而进行了一些更改?2.这是否预示着FP的未来?还是像对象数据库这样的时尚?
其他人给出了很好的技术理由。
我认为FP在普通开发人员和管理人员类型中获得青睐的主要原因是,它有望允许更好地使用多核CPU。从我读过的所有文章中,FP都允许更轻松(而不容易)的并行编程。
如果诺言是真实的并得以实现,那么将来的广泛使用将是。