Simple Scala: Functional Programming

简介

函数式编程实质上比OOP的研究时间要长,FP为我们这个时代的三个主要挑战提供有效的技术:

  • 普遍的并发性需求,因此我们可以横向扩展我们的应用程序,并提高他们对服务中断的韧性,因此并发编程现在时必备技能.
  • 编写大数据应用,最近的大数据趋势突出了用于处理大型数据集的有效技术的重要性.
  • 编写无BUG得应用.

不变性解决了并发问题中最难解决的问题比如同步状态共享和可变状态,因此编写不可变性代码是开发健壮并发程序必不可少的工具.

什么是函数式编程

函数式编程基于数学思维中的函数和值,这对软件开发影响深远.

数学中的函数

在数学中函数是没有副作用的,比如经典的函数sin(x):

y = sin(x)

无论调用多少次上面的函数,sin(x)都会得到同样的值然后赋给y,没有任何类型的公共状态.因此,我们认为这个函数是一个无副作用的函数或纯函数.
纯函数的性质大大简化了分析测试调试函数的挑战.你可以无需了解并脱离任何上下文来调用该函数,但它有时也会调用其他函数.

函数在函数式编程中和数值一样都是是一等公民,可以使用函数组成新的函数,比如 tan(x) = sin(x) / cos(x).可以把函数赋给一个变量,可以把函数当做参数传递给其他函数,也可以从函数从返回一个函数作为结果值.
如果一个函数接收一个函数作为参数或者返回一个函数作为结果值,则这个函数被称为高阶函数.在数学中,高阶函数的两个例子是微积分中的微分和积分.我们通过一个表达式,比如一个函数,通过推导操作,返回一个新的函数的导数.
我们已经见过很多高阶函数的实例,比如集合类型上得map方法,对集合中的每个元素作用一个函数.

变量不是”变量”

变量一词在函数式编程语言中拥有新的含义.如果你属于procedural-oriented programming(面向程序编程)的后台,属于传统的object- oriented programming(面向对象编程)的一个子集,你会习惯于变量时可变的,但是在函数式编程中,变量时不可变的.
这是数学式思维的另一个结果.在表达式y = sin (x),一旦确定了x,y就不能改变了;如果你将3这个对象递增1,你并不能修改3这个对象,而是用一个新的变量来表示4.
如果你不熟悉的话不可变性会难于使用.比如,如果不能修改一个变量,就不能使用循环计数器,当在一个对象上调用方法时就不能改变一个对象的状态,也不能够做输入和输出的操作以改变世界的状态…

但是不可变变量也不是一无是处,你可以创建新的对象实例以表示状态的改变,或调用函数或返回一个值:

def factorial(i: Int): Long = {
    def fact(i: Int, accumulator: Int): Long = {
        if (i <= 1) accumulator
        else fact(i - 1, i * accumulator) 
    }
    fact(i, 1) 
}
(0 to 5) foreach ( i => println(factorial(i)) )

例子中使用递归计算阶乘,把集聚的值放到堆栈上而不去修改.