函数式编程(一):纯函数

其他:函数式编程(二):curry

什么是纯函数?

纯函数是这样一种函数,即相同的输出,永远会得到相同的输出,而且没有任何可观察的副作用。‘副作用’是在计算结果的过程中,系统状态的一种变化,或者与外部世界进行可观察的交互。概括来讲,只要跟函数外部环境发生的交互就都是副作用。函数式编程的哲学就是假定副作用是造成不正当行为的主要原因。并不是说,要禁止使用一切副作用,而是,要让他们在可控的范围内发生。从定义上来说,纯函数必须能根据相同的输入返回相同的输出;如果函数需要跟外部事物打交道,那么就无法保证这一点了。

var	xs	=	[1,2,3,4,5];
//	纯函数
xs.slice(0,3);
//=>	[1,2,3]
xs.slice(0,3);
//=>	[1,2,3]
xs.slice(0,3);
//=>	[1,2,3]

//	非纯函数
xs.splice(0,3);
//=>	[1,2,3]
xs.splice(0,3);
//=>	[4,5]
xs.splice(0,3);
//=>	[]
//	不纯的
var minimum = 21;
var checkAge = function(age) {
	return age >= minimum;
};
//	纯函数
var checkAge = function(age) {
	var minimum = 21;
	return age >= minimum;
};

在不纯的版本中,函数的结果取决于 minimum 这个可变变量的值。换句话说,它取决于系统状态。输入值(参数)之外的因素能够左右函数的返回值,会使函数变得不纯,导致我们思考整个软件是总是要面对函数外部复杂多变的系统状态。

如果一个函数是纯函数,它的输入就直接表明了输出,那么就没有必要实现具体的细节了,因为函数仅仅只是输入到输出的映射。基于这个概念,就可以逐步构建出函数式编程的蓝图。

传统的命令式编程方法和过程都深深地植根于它们所在的环境中,通过状态、依赖和有效作用达成。而纯函数则与环境无关,可以在任何地方运行它,并保证相同的输入总会有相同的结果。

#纯函数的好处

1.引用透明性

所谓的引用透明性就是一段代码可以替换成它执行所得的结果,而且是在不改变整个程序行为的前提下,替换的。而纯函数就是引用透明的。引用透明意味着可以进行等式推导(就像高中数学的推导),等式推导可以为重构和理解代码带来相当大的分析能力。

//太傻
var getServerStuff = function(callback) {
	return ajaxCall(function(json) {
		return callback(json);
	});
};

//这才像样
var getServerStuff = ajaxCall;

//因为
return ajaxCall(function(json) {
	return callback(json);
});

//等价于
return ajaxCall(callback(json));

//而
var getServerStuff = function(callback) {
	return ajaxCall(callback(json));
};

//就等于...
var getServerStuff = ajaxCall;

2.并行代码

纯函数不依赖于系统状态的特点,我们就可以并行运行任意纯函数。因为纯函数根本不需要访问共享的内存,而且根据其定义,纯函数也不会因副作用而进入竞争态。

时间: 2024-10-20 09:09:24

函数式编程(一):纯函数的相关文章

js函数式编程(1)-纯函数

我将写的第一个主题是js的函数式编程,这一系列都是mostly adequate guide这本书的读书总结.原书在gitbook上,有中文版.由于原作者性格活泼,书中夹杂很多俚语,并且行文洒脱.中文译版难免有时需要思量一番,既然读了就写出来,能方便别人最好,也请读者指正.正文如下. 如果一个函数是纯函数,那么其不依赖外部环境,并且不产生副作用. 1.不依赖外部环境,反例如下: const a1 = 10; const aFunc1 = () => { // 依赖外部变量 return a1;

函数式编程—高阶函数

一.函数式编程概念简介 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元 就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如C语言:越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Lisp语言 函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种

Python之路Python作用域、匿名函数、函数式编程、map函数、filter函数、reduce函数

Python之路Python作用域.匿名函数.函数式编程.map函数.filter函数.reduce函数 一.作用域 return 可以返回任意值例子 def test1(): print("test1") def test(): print("test") return test1 res = test() print(res) 输出结果 test <function test1 at 0x021F5C90> 分析:这里print(res)输出的是te

函数式编程中的函数—函数式编程的多态

函数式编程中的函数—函数式编程的多态 保存了计算上下文和计算过程的特殊值 保存了计算上下文和计算过程的有输入输出的可计算结构. 保存了计算上下文和计算过程的可配置结构:(柯里化). 函数作为一种特殊的值和结构,可以由更高阶的函数对其进行组合.变换.柯里化等操作: 函数作为输入和输出:本质上都是可配置.可计算结构. 可配置的是作为参量输入的计算上下文: 可计算是计算上下文配置完备后直接进行计算: 普通函数: 参数函数(闭包函数): 高阶函数: 返回函数(内部函数): 值函数:被其它函数引用和调用的

Python进阶:函数式编程(高阶函数,map,reduce,filter,sorted,返回函数,匿名函数,偏函数)...啊啊啊

函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. 而函数式编程(请注意多了一个"式"字)--Functional Programming,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算. 我们首先要搞明白计算机(Computer)和计算(Compute)的概念. 在计算机的层次上,CPU执行的是加减乘除的指令代码

C#函数式编程之由函数构建函数

在面向对象的编程中,如果我们需要复用其他的类,我们可以通过继承来实现.而在函数式编程中我们也可以采取不同的方式来复用这些函数.今天的教程将会讲述两种方式,其中一个就是组合,将多个函数组合成为一个函数,另一个则是之前我们介绍过的部分应用,当然我们将会讲述如何将其高级化,来符合我们的使用要求. 组合 顾名思义,组合就是将函数A的结果传递给函数B.但是我们并不关注函数A的结果,当然大多数一定会这样去做: 1 var r1 = funcA(1); 2 var r2 = funcB(r1); 这样显然不是

Python(十) 函数式编程: 匿名函数、高阶函数、装饰器

一.lambda表达式 lambda parameter_list: expression # 匿名函数 def add(x,y): return x+y print(add(1,2)) f = lambda x,y: x+y print(f(1,2)) 二.三元表达式 # x >y ? x :y # 条件为真时返回的结果 if 条件判断 else 条件为假时的返回结果 x= 2 y=1 r = x if x > y else y print(r) # 2 三.map 四.map与lambda

Python函数和函数式编程(2): 匿名函数--lambda

原文地址:http://blog.csdn.net/majianfei1023/article/details/45269343 一. lambda函数: lambda函数也叫匿名函数,函数没有具体的名称.先来看一个最简单例子: def f(x): return x * 2 g = lambda x : x * 2 看一下 f 和 g的写法有什么不同,f是定义了一个函数,传进去一个参数x,然后x*2,g是定义了一个lambda,后面跟着一个x(这个就是参数),然后跟着一个 : x * 2 (这就

Python自学笔记之函数式编程6——匿名函数

我们传入函数时,有时候不需要显式地定义函数,直接传入匿名函数更方便. 在Python中,对匿名函数提供了有限支持.以map()函数为例,计算f(x) = x * x时,除了定义一个f(x)的函数外,还可以直接传入匿名函数: >>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])) [1, 4, 9, 16, 25, 36, 49, 64, 81] 通过对比可以看出,匿名函数lambda x: x * x实际上就是: def f

Python 函数式编程--高阶函数Map、Reduce、Filter、Sorted

1.1   高阶函数 变量可指向函数 >>> abs(-10) 10 >>> x = abs    --x指向abs函数 >>> x(-1)      --直接调用x 1 调用abs和调用x完全相同. 函数名也是变量 >>> abs = 10 >>> abs(-10) Traceback (most recent call last): File "<stdin>", line 1,