Welcome 微信登录

首页 / 软件开发 / JAVA / 浅谈Java 8的函数式编程

浅谈Java 8的函数式编程2014-11-07 infoq Ben Evans 译:梅雪松关于“Java 8为Java带来了函数式编程”已经有了很多讨论,但这句话的真正意义是什么?

本文将讨论函数式,它对一种语言或编程方式意味着什么。在回答“Java 8的函数式编程怎么样”之前,我们先看看Java的演变,特别是它的类型系统,我们将看到Java 8的新特性,特别是Lambda表达式如何改变Java的风景,并提供函数式编程风格的主要优势。

函数式编程语言是什么?

函数式编程语言的核心是它以处理数据的方式处理代码。这意味着函数应该是第一等级(First-class)的值,并且能够被赋值给变量,传递给函数等等。

事实上,很多函数式语言比这走得更远,将计算和算法看得比它们操作的数据更重要。其中有些语言想分离程序状态和函数(以一种看起来有点对立的方式,使用面向对象的语言,这通常会将它们联系得更紧密)。

Clojure编程语言就是一个这样的例子,尽管它运行于基于类的Java虚拟机,Clojure的本质是函数式语言,并且在高级语言源程序中不直接公布类和对象(尽管提供了与Java良好的互操作性)。

下面显示的是一个Clojure函数,用于处理日志,是一等公民(First-class citizen),并且不需要绑定一个类而存在。

(defn build-map-http-entries [log-file] (group-by :uri (scan-log-for-http-entries log-file)))
当写在函数中的程序,对给定的输入(不论程序中的其它状态如何)总是返回相同的输出,并且不会产生其它影响,或者改变任何程序状态,这时候函数式编程是最有用的。它们的行为与数学函数相同,有时候把遵循这个标准的函数称为“纯”函数。

纯函数的巨大好处是它们更容易推论,因为它们的操作不依赖于外部状态。函数能够很容易地结合在一起,这在开发者工作流风格中很常见,例如Lisp方言和其它具有强函数传统的语言中很普遍的REPL(Read, Execute, Print, Loop)风格。

非函数式编程语言中的函数式编程

一种语言是不是函数式并不是非此即彼的状态,实际上,语言存在于图谱上。在最末端,基本上是强制函数式编程,通常禁止可变的数据结构。Clojure就是一种不接受可变数据的语言。

不过,也有一些其它语言,通常以函数方式编程,但语言并不强制这一点。Scala就是一个例子,它混和了面向对象和函数式语言。允许函数作为值,例如:

val sqFn = (x: Int) => x * x
同时保留与Java非常接近的类和对象语法。

另一个极端,当然,使用完全非函数式语言进行函数式编程是可能的,例如C语言,只要维持好合适的程序员准则和惯例。

考虑到这一点,函数式编程应该被看作是有两个因素的函数,其中一个与编程语言相关,另一个是用该语言编写的程序:

1)底层编程语言在多大程度上支持,或者强制函数式编程?

2)这个特定的程序如何使用语言提供的函数式特性?它是否避免了非函数式特性,例如可变状态?