在个人平常工做中,我身边的开发者大可能是毕业于CS编程顶级院校好比MIT、CMU以及Chicago,他们初次涉及的语言是Haskell、Scheme及Lisp。他们认为函数式编程是一种天然的、直观的、美丽的且高效的编程样式。但奇怪的是,我和个人同事并无为Haskell、Scheme、Lisp、Clojure、Scala而编程,这个行业里的绝大部分人都会使用Python、 Ruby、Java或C#等编程,由于它们用起来比较顺手。但在Java中,函数式编程倒是低效且危险的。java
为何函数式编程在Java中很危险呢?程序员
每隔几个月,我都会在调试中发现问题,究其缘由最终可追溯到滥用函数的想法以及编程算法,更重要的缘由是这个虚拟机没法建立这种编程样式。算法
最近Bob Martin想出一个很好的例子并说明了缘由。Clojure (一个真正的函数式编程)返回到25整数列表:编程
此代码运行和响应速度都很快,输出结果:安全
如今,假设咱们想要在Java中重写,若是咱们以Gosling的方式来编写Java,那么该代码是简单、快速且明显的:函数式编程
可是,如今假设咱们让它变得多功能性,在特定的假设范围内重置上面的Clojure样式:函数
尝试运行吧,OK,从堆转储(Heap Dump)中恢复 ?性能
当Java输出后,Clojure如何处理函数,使该函数可返回到每个int?学习
Clojure如同全部真正的函数语言(与Java不一样)具有懒散赋值特性。它(指clojure)不会计算不被使用的值。它能够远离这个,由于Clojure不像Java,它是真正函数式语言,能够假定变量不发生变异,使求值的顺序变得可有可无。所以,Clojure能够执行优化,可是Java编译器却不能——这就是为何函数式编程在Java中是危险的缘由。由于,Java不是真正的函数式语言,JIT和javac没法像在一个真正的函数式语言中积极且有效地优化函数构造对象,好比返回无穷个列表的标准函数计算,都是Java程序的死穴。这也是为何函数式编程在Java中危险的缘由。优化
这里,也许你会反对个人观点,OK,你无须在Java中返回全部的整数列表(或者甚至是全部的ints);可是相信没人作到这一点。
咱们来一块儿看看比较现实的作法。这里我再次使用递归来计算而不是循环:
开始运行!
很抱歉,堆栈溢出。这就是为何在XOM中我当心翼翼地使用循环,即便递归的地方十分清楚也不使用递归。不然,精心配置XML文档可能会形成XOM-using程序来转储核心。所以,避免在非函数式语言中进行大量递归,正如Java和C不只仅是性能需求,也是安全方面的要求。
写在最后:
我不是说函数式编程很差,也不是说函数式编程低效,其实,我热爱函数式编程。就像个人同事认为函数式编程是天然、直观且美丽的编程风格,但当它做为一们语言好比为Haskell从新设计时,Java中函数语句的性能Bug绝对能要了你的命。