Scala 函数式编程

原创 2015年07月10日 10:25:43

a、什么是函数式编程

函数式编程是一种编程范式(即编写程序的方法论),它主要通过组合方式,将运算过程组合成一系列的函数调用。如下的数学表达式:

(1 + 2) * 3 - 4
传统的过程式编程,可能这样写:

var a = 1 + 2
var b = a * 3
var c = b - 4
而函数编程则就要将每个运算过程定义为不同的函数,然后组合起来使用,返回最终的计算结果。如下
var result = subtract(multiply(add(1,2), 3), 4);
这就是函数式编程。

b、函数式编程和面向对象编程的区别

函数式编程和面向对象编程是两种不同的看待问题的方式,函数式编程强调的是“动词(verbs)”以及如何组合和调用它们。而面向对象编程强调的是”名词(nouns)“以及它们所具有的动作。

面向对象编程中,每个对象都有标识符、方法、状态(成员变量)。在标识对象、对象状态、行为后,对象之间的交互就成了问题,因为交互需要在一个对象里完成。现在常用的方法是创建一个服务类(Service Class),它包含一个跨多个域对象的操作集合。服务类也是一个对象,它没有状态或行为独立于其操作对象的概念。

函数式编程侧重于函数的组合和应用,所有的变量都是不可变的,并且尽可能的消除副作用,这些都有利于并发编程。

举个例子,分别采用面向对象编程和函数式编程的方式,对下面的一句话编程:

一只猫捕捉了一只鸟,并吃了它。
采用面向对象编程的方式,可以从这句话中提取出两个名词:猫、鸟,并且猫具有“捕捉”和“吃”的动作。代码如下:

class Bird
class Cat {
  def catch(b: Bird): Unit = ...
  def eat(): Unit = ...
}
val cat = new Cat
val bird = new Bird
cat.catch(bird)
cat.eat()
采用函数是编程的方式,则应关注“动词”

trait Cat
trait Bird
trait Catch
trait FullTummy

def catch(hunter: Cat, prey: Bird): Cat with Catch
def eat(consumer: Cat with Catch): Cat with FullTummy

val story = (catch _) andThen (eat _)
story(new Cat, new Bird)

c、函数式编程的特点

1、函数是“第一等公民”

所谓的“第一等公民”是指,函数和其它的数据类型一样,处于平等地位,它可以给变量赋值,可以作为参数传入另一个函数,也可以作为别的函数的返回值。

2、只用表达式,不用语句

“表达式”指的是一个单纯的运算过程,总有返回值;而“语句”是执行某种操作,没有返回值。函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。

3、没有“副作用”

所谓的“副作用”是指,函数内部与外部的交互,不会改变外部的状态,例如修改外部的成员变量或修改全局变量的值等。

4、引用透明性

引用透明性是指函数的运行不依赖与外部的变量或状态,只依赖与输入的参数,只要输入的参数相同,输入的结果始终是相同的。

关于“引用透明性”的理解,还可详见这篇文章:http://blog.csdn.net/qiruiduni/article/details/46831461


d、函数式编程的优点

1、代码简洁,开发快速

函数式编程大量使用函数,减少了代码的重复,因此程序比较短,开发速度快。

2、接近自然语言,易于理解

函数式编程的自由度很高,可以写出很接近自然语言的代码。

前文曾经将表达式(1 + 2) * 3 - 4,写成函数式语言:

subtract(multiply(add(1,2), 3), 4)
对它进行变形,不难得到另一种写法:

add(1,2).multiply(3).subtract(4)
这基本就是自然语言的表达了。再看下面的代码,大家应该一眼就能明白它的意思吧:

merge([1,2],[3,4]).sort().search("2")

因此,函数式编程的代码更容易理解。

3、更方便的代码管理

函数式编程不依赖、也不会改变外界的状态,只要给定输入参数,返回的结果必定相同。因此,每一个函数都可以被看做独立单元,很有利于进行单元测试(unit testing)和除错(debugging),以及模块化组合。

4、易于“并发编程”

函数式编程不需要考虑"死锁"(deadlock),因为它不修改变量,所以根本不存在"锁"线程的问题。不必担心一个线程的数据,被另一个线程修改,所以可以很放心地把工作分摊到多个线程,部署"并发编程"(concurrency)。

请看下面的代码:

  var s1 = Op1();
  var s2 = Op2();
  var s3 = concat(s1, s2);
由于s1和s2互不干扰,不会修改变量,谁先执行是无所谓的,所以可以放心地增加线程,把它们分配在两个线程上完成。其他类型的语言就做不到这一点,因为s1可能会修改系统状态,而s2可能会用到这些状态,所以必须保证s2在s1之后运行,自然也就不能部署到其他线程上了。

多核CPU是将来的潮流,所以函数式编程的这个特性非常重要。

5、代码的热升级

函数式编程没有副作用,只要保证接口不变,内部实现是外部无关的。所以,可以在运行状态下直接升级代码,不需要重启,也不需要停机。Erlang语言早就证明了这一点,它是瑞典爱立信公司为了管理电话系统而开发的,电话系统的升级当然是不能停机的。



Scala函数式编程设计原理 第一课 编程范式(Programming Paradigms)

我使用Scala有一两年的时间了,这门语言仿佛有一种魔力,让人用过就不想放手。Scala给我的整个程序生涯带来了非常深刻的影响,让我学会了函数式编程,让我知道了世界上居然还有这么一种优雅、高效、强大的...
  • i6448038
  • i6448038
  • 2016年05月08日 15:54
  • 3553

第3讲:Scala函数式编程彻底精通

简介: 本篇博文主要是对Scala函数式编程的彻底详解,涉及高阶函数,闭包,颗粒化等详解。 1. Scala函数式编程 Scala中的函数的可以不依赖类或则借口,独立存在,甚至...
  • snail_gesture
  • snail_gesture
  • 2016年02月03日 11:37
  • 2049

深入理解Scala中的函数式编程

核心内容: 1、Scala中函数的地位:一等公民 2、Scala中的匿名函数(函数字面量) 3、Scala中的高阶函数 4、Scala中的闭包 5、Scala中的部分应用函数 6、Scal...
  • a2011480169
  • a2011480169
  • 2016年11月13日 21:34
  • 3827

Spark学习笔记3-Scala函数式编程

1.函数1.1函数的定义scala中函数的定义如下代码:scala> def fun1(name: String){println(name)} fun1: (name: String)Unit代码是...
  • xummgg
  • xummgg
  • 2016年01月24日 21:11
  • 1037

[scala]函数式编程思想入门

1.python闭包的栗子 def make_adder(addend): def adder(augend): return augend + addend ret...
  • u014265088
  • u014265088
  • 2016年09月27日 10:37
  • 1159

Scala:Function(高阶函数式编程)

本篇介绍Scala中一个可以进行高阶函数式编程的模块,我们来看看它都实现了哪些操作,并结合源码理解一下。...
  • bdmh
  • bdmh
  • 2015年12月03日 16:23
  • 2838

scala学习六:scala函数式编程进阶

scala学习六:scala函数式编程进阶标签(空格分隔): scalascala学习六scala函数式编程进阶 一集合 二列表 三序列 四集 五模式匹配 六Case Class 一,集合不可变集合:...
  • youfashion
  • youfashion
  • 2016年06月18日 18:37
  • 669

scala与函数式编程——从范畴论看函数式编程

什么是范畴?  其实范畴Category就是指一群事物以及这些事物之间的所有关联关系,这些事物和这些关联关系共同组成了某个范畴。 函数式编程所描绘的范畴,是一个以数据类型为点,以函数为箭头,并且充满...
  • samsai100
  • samsai100
  • 2017年05月09日 22:41
  • 302

Coursera公开课Functional Programming Principles in Scala习题解答:Week 2

引言 OK.时间很快又过去了一周,第一周有五一假期所以感觉时间绰绰有余,这周中间没有假期只能靠晚上加周末的时间来消化,其实还是有点紧张呢!后来发现每堂课的视频还有对应的课件(Slide)、字幕(sub...
  • doggie_wangtao
  • doggie_wangtao
  • 2014年05月14日 00:21
  • 3109

Scala函数式编程课后习题答案(第三章)(更新ing)

Scala函数式编程课后习题答案(第三章)
  • dlke03
  • dlke03
  • 2017年05月11日 14:12
  • 667
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Scala 函数式编程
举报原因:
原因补充:

(最多只允许输入30个字)