为什么我们需要学习函数式编程?或者说函数式编程有什么优势?这个系列中我会用 scala 给你讲述函数式编程中的优势,以及一些函数式的哲学。不懂 scala 也没关系,scala 和 java 是类似的,在每篇的开头我也会先说明这节中用到的 scala 语法。

为什么函数式编程这几年火起来

如 Python 一样,函数式编程(FP,即Functional Programming)也是近几年才逐渐为人们所知,但它并不是一个多么新的概念。它拥有和面向对象编程(OOP)几乎等长的历史。但纵观每件事的脉络,总是有原因的,函数式编程这几年变火的原因是什么呢?

最主要的原因是摩尔定律的逐渐失效,计算机的发展道路趋向于多核 CPU 与分布式的方向。我们经常使用的面向对象编程的优势在于能够很好得对要解决的问题领域进行建模,但它在多线程编程环境下的同步阻塞调用,以及由此带来的线程安全问题,与函数式编程天然适合分布式并发编程的编程方式相比,当真相形见绌。而未来明显是大数据的时代,故而函数式编程只会越加重要,甚至未来可能是函数式编程的时代。

摩尔定律:1965年,英特尔公司创始人戈登·摩尔提出,在至多10年内,集成电路的集成度会每两年翻一番,即摩尔定律。后来这个周期被缩短到了18个月。也就是说,每隔18个月,计算机等IT产品的性能就会翻一番;或者说相同性能的计算机等IT产品,每18个月价钱会降一半。几十年来IT行业的发展始终遵循着摩尔定律预测的速度。

函数式编程思想介绍

有一篇有趣的文章,或许可以让你对函数式编程有所了解,可以先看看它,稍后再看看对函数式的正式定义,函数式编程圣经

所谓函数式编程,其实就是以纯函数的方式编写代码,纯函数的定义如下:

纯函数:一个函数在程序的执行过程中除了根据输入参数给出运算结果之外没用其他影响,就可以说是没有副作用的,我们就可以将这一类函数称之为纯函数

纯函数最核心的目的是为了编写无副作用的代码,它的很多特性,包括不变量,惰性求值等等都是为了这个目标。那什么叫做无副作用呢?我们用一个例子来看看。

咖啡店购物的例子 --scala

先来看一段有副作用(非函数式)的代码

class Cafe {
//用户购买一杯咖啡执行的函数
def buyCoffee(Cc: CreditCard) : Coffee = {
val cup = new Coffee()
//副作用所在,除了返回一杯咖啡,它还去通知信用卡公司扣费
cc.charge(cup.price)
cup
}
}

这个函数的副作用是什么呢?就是在购买了一杯咖啡的时候使用信用卡去计费,它会通知信用卡公司去进行一系列处理。

这样会导致什么问题呢?首先,副作用会让这段代码变成线程不安全。其次,会让这段代码难以测试,如果想测试这段代码的逻辑,就不得不每次都让信用卡扣费。但我们只是想测试一下逻辑而已,并不想真正扣费。再者,当你想要一次购买多杯咖啡的时候怎么办,你只能跳脚。



这时候我们再看看函数式的方式去实现:

函数式的咖啡店

case class Charge(cc: CreditCard,amount: Double)
class Cafe{
def buyCoffee(cc:CreditCard) : (Coffee,Charge) = {
val cup = new Coffee()
(cup,Charge(cc,cup.price))
}
}

看到了吗,经过我们这样改变之后,函数变得没有副作用了。也就是说,无论执行这个 buyCoffee 函数多少次,它只会返回给我一杯咖啡以及它的价钱,这样我们就可以很方便得对它的逻辑进行测试而不必担心影响到信用卡。并且它可以安全得运行在多线程环境下。

其实从面向对象的角度来看,这是不是有点像面向对象里面的一些设计模式呢?这样做解耦了咖啡和信用卡之间的关系,在后面添加其他功能的时候我们可以方便得进行组合,比如说想要有一个多杯咖啡计费的功能,如果是用上面那段代码来实现需求,那么无疑会很痛苦。但通过函数式的方式改编后,一些变得清晰起来~

从这个角度来说,函数式编程其实也可以是一种编程思维,它无法帮你立即获得更好的职位,但却可以从某种程度上改变你编程的思维,让你写出更优秀的代码。

结语

最近几年,很多新火起来的概念,但它们其实早在上世纪就已经被发明出来,无论时机器学习,深度学习,Python语言,还是函数式编程。这是为什么呢?这是因为这些技术的边界发生变化,或者说这个时代的技术边界变了。

每个时代都有每个时代的技术边界,真正的工程师会知道边界在哪里,只有外行才会无法无边。巴菲特说他不投资自己不懂的东西,正是因为他给自己的划定了一个边界。

苹果公司能够成功的一个重要原因正是因为它清楚得知道时代的边界,并且能在边界内做到最好。你看苹果很多产品都具有划时代的意义是吧,但其实那些产品都不是苹果首创,比如智能手机,最早是日本公司 DOCOMO 发明,个人平板电脑是英国首先发明。IPod,MP3 也是韩国先出品的。苹果公司用的很多技术甚至在 30 年前就有了,但为什么直到被发明出来才为人们所知?

正是因为苹果了解时代的技术边界,并在边界内做到最好。

往小了说,当我们在学习新的技术,或是使用新技术完成某项工作的时候,我们一定要直到它的边界在哪里。往大了说,我们应该像苹果一样,多多思考这个时代的技术边界在哪里,这样才不至于陷入无休止的技术追赶之中。

Scala 函数式编程(一) 什么是函数式编程?的更多相关文章

  1. Scala函数式编程(四)函数式的数据结构 下

    前情提要 Scala函数式编程指南(一) 函数式思想介绍 scala函数式编程(二) scala基础语法介绍 Scala函数式编程(三) scala集合和函数 Scala函数式编程(四)函数式的数据结 ...

  2. Scala函数式编程(五) 函数式的错误处理

    前情提要 Scala函数式编程指南(一) 函数式思想介绍 scala函数式编程(二) scala基础语法介绍 Scala函数式编程(三) scala集合和函数 Scala函数式编程(四)函数式的数据结 ...

  3. [一] java8 函数式编程入门 什么是函数式编程 函数接口概念 流和收集器基本概念

      本文是针对于java8引入函数式编程概念以及stream流相关的一些简单介绍 什么是函数式编程?   java程序员第一反应可能会理解成类的成员方法一类的东西 此处并不是这个含义,更接近是数学上的 ...

  4. Java编程的逻辑 (92) - 函数式数据处理 (上)

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  5. Java中的函数式编程(二)函数式接口Functional Interface

    写在前面 前面说过,判断一门语言是否支持函数式编程,一个重要的判断标准就是:它是否将函数看做是"第一等公民(first-class citizens)".函数是"第一等公 ...

  6. Java函数式编程:一、函数式接口,lambda表达式和方法引用

    Java函数式编程 什么是函数式编程 通过整合现有代码来产生新的功能,而不是从零开始编写所有内容,由此我们会得到更加可靠的代码,并获得更高的效率 我们可以这样理解:面向对象编程抽象数据,函数式编程抽象 ...

  7. 学习响应式编程 Reactor (1) - 响应式编程

    响应式编程 命令式编程(Imperative Programing),是一种描述计算机所需做出的行为的编程范式.详细的命令机器怎么(How)去处理以达到想要的结果(What). 声明式编程(Decla ...

  8. 函数式接口的概念&函数式接口的定义和函数式接口的使用

    函数式接口概念 函数式接口在Java中是指:有且仅有一个抽象方法的接口. 函数式接口,即适用于函数式编程场景的接口.而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambd ...

  9. [.net 面向对象编程基础] (2) 关于面向对象编程

    [.net 面向对象编程基础]  (2)  关于面向对象编程 首先是,面向对象编程英文 Object-Oriented Programming 简称 OOP 通俗来说,就是 针对对象编程的意思 那么问 ...

  10. 5天玩转C#并行和多线程编程 —— 第五天 多线程编程大总结

    5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编 ...

随机推荐

  1. 微信小程序把玩(八)view组件

    原文:微信小程序把玩(八)view组件 刚看到这个效果的时候还真是和ReactNative的效果一致,属性也基本的一样. view这个组件就是一个视图组件使用起来非常简单. 主要属性: flex-di ...

  2. java的static类(静态内部类)(转载)

    转载自:http://www.jb51.net/article/74838.htm java中的类可以是static吗?答案是可以.在java中我们可以有静态实例变量.静态方法.静态块.类也可以是静态 ...

  3. Visual studio调试Web发生未能正常启动IIS express

    今天调试web时,不知道怎么搞的,昨天还好好的,结果今天怎么也没法调试了.VS里报的错误是进程号为**的未能正常启动,看了下调试时IIS压根就没启动起来,没关系,看看事件管理器里发生了什么 找到个最关 ...

  4. HTTP通信过程原理

    HTTP协议 通信过程介绍 HTTP协议介绍 Http(Hypertext Transfer Protocol)超文本传输协议. Http是应用层协议,当你上网浏览网页的时候,浏览器和服务器之间就会通 ...

  5. 腾讯云直播录制遇到的bug

    1.录制方式应用:   初始化方法   [[TXUGCRecordshareInstance] startCameraCustom:param preview:_showPlayerView]; ID ...

  6. Java算法-求最大和的子数组序列

    问题:有一个连续数组,长度是确定的,它包含多个子数组,子数组中的内容必须是原数组内容中的一个连续片段,长度不唯一,子数组中每个元素相加的结果称为子数组的和,现要求找出和最大的一个子数组. 具体算法如下 ...

  7. Keepalived双主模式配置流程

    实验说明 1)keepalived 支持配置多个VRRP实例,每个实例对应一个业务 2)本次实验将实现 keepalived 的互为主备: 业务A:keepalived01为Master,keepal ...

  8. 如何有效预防XSS?这几招管用!!!

    原文链接 预防XSS,这几招管用 最近重温了一下「黑客帝国」系列电影,一攻一防实属精彩,生活中我们可能很少有机会触及那么深入的网络安全问题,但工作中请别忽略你身边的精彩 大家应该都听过 XSS (Cr ...

  9. 【转载】JDK自带的log工具

    版权声明:本文为Jaiky_杰哥原创,转载请注明出处.This blog is written by Jaiky, reproduced please indicate. https://blog.c ...

  10. 【设计模式】行为型03观察者模式(Observer Pattern)

    记得16年初第一次学习了23种设计模式,但是除了少数几个简单的外,其他的很多都是学了个似懂非懂,以至于有人问起甚至说不上来,现在想想,其实就是没看懂而已.例如观察者模式,其实原理很简单,但是当时并没有 ...