函数式编程与响应式编程
编程范式
编程范式,又称为编程模型,泛指软件编程过程中使用的编程风格,常见的编程范式包括命令式编程(面向对象、面向过程等),声明式编程(响应式、函数式),
命令式编程 是面向计算机硬件的抽象,有变量、赋值语句、表达式、控制语句等,可以理解为 命令式编程就是冯诺伊曼的指令序列。 它的主要思想是关注计算机执行的步骤,即一步一步告诉计算机先做什么再做什么。
声明式编程 是以数据结构的形式来表达程序执行的逻辑。声明式编程范式关注的焦点不是采用什么算法或者逻辑来解决问题,而是描述、声明解决的问题是什么。当你的代码匹配预先设定好规则,业务逻辑就会被自动触发执行。SQL、HTML 、XML、 CSS 都属于声明式编程。它的特点:1.它不需要创建变量用来存储数据 2.另一个特点是它不包含循环控制的代码。
如图:

函数式编程
函数式编程是面向数学的抽象,将计算描述为一种表达式求值,其实,函数式程序就是一个表达式。函数式编程中的函数并部署指计算机中的函数,而是指数学中的函数,即自变量的映射。函数的值取决于函数的参数的值,不依赖于其他状态,比如abs(x)函数计算x的绝对值,只要x不变,无论何时调用、调用次数,最终的值都是一样。
核心理念
函数是第一等公民:函数是第一等公民:是指函数跟其它的数据类型一样处于平等地位,可以赋值给其他变量,可以作为参数传入另一个函数,也可以作为别的函数的返回值。
函数是纯函数:纯函数是指相同的输入总会得到相同的输出,并且不会产生副作用的函数。无副作用 指的是函数内部的操作不会对外部产生影响(如修改全局变量的值、修改 dom 节点等)。
不可变性:没有可变变量、类似代数变量
迭代是通过递归实现的:没有循环结构
优势
确定性:消除了多线程中的数据竞争问题
同一个输入始终产生同一个输出,结果可缓存、结果可测试
只要编译成功,就能成功运行,不受可变性影响
函数合成(compose)
指的是将代表各个动作的多个函数合并成一个函数。
高阶函数
在函数式编程中,函数被称为first class,意思是函数与值一样,可以作为函数参数传入函数,也可以作为函数返回值返回。
高阶函数:将函数作为参数或返回值的函数。
函数复合
在函数式编程中,函数的复合和数学函数复合概念一致,想法是通过组合更小的、更简单的函数构建更大的、更复杂的函数。
嵌套调用与复合运算符
1 |
|
函数柯里化currying
函数柯里化又称部分求值,指的是将多参数函数转换为单参数函数的特性。一个柯里化的函数首先会接受一些参数,接受了这些参数之后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值
解析
1 |
|
例子
1 |
|
闭包closure
函数与其词法环境的组合就是闭包。
lambda函数
语法
- lambda 函数的语法只包含一个语句,表现形式如下:
lambda [arg1 [,arg2,.....argn]]:expression
- 其中,lambda 是 Python 预留的关键字,[arg…] 和 expression 由用户自定义。
- 具体介绍如下:
[arg…] 是参数列表,它的结构与 Python 中函数(function)的参数列表是一样的,如下。
1 |
|
- expression 是一个参数表达式,表达式中出现的参数需要在
[arg......]
中有定义,并且表达式只能是单行的,只能有一个表达式。
lambda 特性
lambda 函数是匿名的:所谓匿名函数,通俗地说就是没有名字的函数。lambda函数没有名字。
lambda 函数有输入和输出:输入是传入到参数列表argument_list的值,输出是根据表达式expression计算得到的值。
lambda 函数拥有自己的命名空间:不能访问自己参数列表之外或全局命名空间里的参数,只能完成非常简单的功能。
常见的lambda函数示例:
1 |
|
lambda 常见用法
将lambda函数赋值给一个变量,通过这个变量间接调用该lambda函数。
add = lambda x, y: x+y
将lambda函数赋值给其他函数,从而将其他函数用该lambda函数替换。
将lambda函数作为参数传递给其他函数。
响应式编程
Wikipedia: 在计算中,响应式编程或反应式编程(英语:Reactive programming)是一种面向数据流和变化传播的声明式编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。
目的:提高应用程序的性能和可伸缩性,以应对高并发和高负载的场景。
实现
观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
Reactor 中大部分实现都是按照上图的逻辑来执行的:
- 首先是Subscriber(订阅者)主动订阅 Publisher(发布者),通过调用 Publisher 的 subscribe 方法
- Publisher 在向下游发送数据之前,会先调用 Subscriber 的 onSubscribe 方法,传递的参数为 Subscription(订阅媒介)
- Subscriber 通过 Subscription#request 来请求数据,或者 Subscription#cancel 来取消数据发布(这就是响应式编程中的背压,订阅者可以控制数据发布)
- Subscription 在接收到订阅者的调用后,通过 Subscriber#onNext 向下游订阅者传递数据。
- 在数据发布完成后,调用 Subscriber#onComplete 结束本次流,如果数据发布或者处理遇到错误会调用 Subscriber#onError