副作用(Side Effect)是指函数或者表达式的行为依赖于外部世界。具体可参照Wiki上的定义,副作用是指

1)函数或者表达式修改了它的SCOPE之外的状态

2)函数或者表达式除了返回语句外还与外部世界或者它所调用的函数有明显的交互行为



对于1)而言,考虑如下函数定义:

int se(int * p){
(*p)++;
return *p;
}

以及caller:

void foo(){
int k = 1;
int * p = &k;
se(p);
}

几乎可以按照定义逐字匹配,se(int *)函数修改了域外(CALLER FUNCTION)的变量k的状态(++),所以se(int *)函数具有副作用

在2)中可以认为外部世界是相对于程序不确定的外部因素,如计算机实体(磁盘,内存条),用户输入行为等。



副作用是区别函数式编程语言和当今主流的面向对象/过程式编程语言的显著特征。在面向对象/过程式中变量(VARIABLE)是可以改变的量,一如代码实现。

int a = 1;
a = 2;
change(a,3);

对于"="的行为我们都知道:

哦,这是给变量一个值,如果我发现这个值不能满足我的需求还可以重新给它值。

赋值运算符提供了面向对象/过程式编程语言绝大部分的副作用。如果懂得这一点在面对函数式语言的"="的时候就不会惊恐,函数式之所以声称(几乎)无副作用就是因为它的"="有别于传统观念上的赋值行为,在函数式中"="是匹配(Match)运算符,对于没有进行绑定的变量第一次使用匹配运算符发生绑定行为,如erlang中

X = atom. %ok
X = newAtom. %error

可以看到当变量X第一次使用"="与atom绑定之后对其使用"="就会发生匹配行为而不是重新绑定,作为更强烈的论证可以看到

atom = X. %ok, match variable with atom 

绑定后的X可以放到匹配运算符的左边。

匹配行为不与外部世界发生交互,它不会修改外部世界的任何状态,所以这也解释了函数式编程语言为什么几乎无副作用,不说"完全"是因为只要有IO就有副作用,没有IO的语言..我没见过.

正是因为(几乎)无副作用使得函数式编程语言在数学定义证明,并发处理等方面有天然的优势。

什么是副作用(Side Effect)的更多相关文章

  1. [转载]C++的顺序点(sequence point)和副作用(side effect)

    有关i=(++i)+(i++)这种东西的深入解释,不仅仅是简单粗暴undefined behavior. ==== 一.副作用(side effect) 表达式有两种功能:每个表达式都产生一个值( v ...

  2. 浅谈C/C++中的顺序点和副作用

    一.副作用(side effect) 表达式有两种功能:每个表达式都产生一个值( value ),同时可能包含副作用( side effect ).副作用是指改变了某些变量的值. 如: 1:20    ...

  3. side Effect

    副作用 side Effect 副作用是在计算结果的过程中,系统状态的一种变化,或者与外部世界进行的可观察的交互. 副作用可能包含,但不限于: 1.更改文件系统 2.往数据库里插入数据 3.发送一个h ...

  4. 《编程导论(Java)·3.1.2 方法》之 副作用

    4. 副作用 在一些语言如Pascal中,子程序被分成两种:函数和过程.尽管Java没有强制性地要求将方法区分为命令和函数.然而这样的差别对于良好地设计程序有非常大的帮助[1]. 首先说明一个概念:副 ...

  5. petite-vue源码剖析-逐行解读@vue-reactivity之effect

    当我们通过effect将副函数向响应上下文注册后,副作用函数内访问响应式对象时即会自动收集依赖,并在相应的响应式属性发生变化后,自动触发副作用函数的执行. // ./effect.ts export ...

  6. 【原创】Kakfa utils源代码分析(二)

    我们继续研究kafka.utils包 八.KafkaScheduler.scala 首先该文件定义了一个trait:Scheduler——它就是运行任务的一个调度器.任务调度的方式支持重复执行的后台任 ...

  7. JavaScript 与函数式编程

    原文:https://bethallchurch.github.io/JavaScript-and-Functional-Programming/ 译文:http://www.zcfy.cc/arti ...

  8. Clojure学习笔记(二)——函数式编程

    定义 “函数式编程”是一种编程范式(programming paradigm),即如何编写程序的方法论.主要思想是把运算过程尽量写成一系列嵌套的函数调用. 举例来说,现在有这样一个数学表达式: (1 ...

  9. 编程实践中C语言的一些常见细节

    对于C语言,不同的编译器采用了不同的实现,并且在不同平台上表现也不同.脱离具体环境探讨C的细节行为是没有意义的,以下是我所使用的环境,大部分内容都经过测试,且所有测试结果基于这个环境获得,为简化起见, ...

随机推荐

  1. jq获取浏览器的高度

    // console.log("2-"+$(window).height()); //浏览器当前窗口可视区域高度 // console.log("3-"+$(d ...

  2. Shell脚本数据备份

  3. 延迟执行之 Invoke 函数

    Invoke 函数需要继承 MonoBehaviour 类后才能使用. Invoke(string str,float a):a 秒后执行名为 str 函数(只会调用一次). Invoke(strin ...

  4. 组合模式(Composite)

    组合模式(Composite) 组合模式有时又叫部分-整体模式在处理类似树形结构的问题时比较方便,看看关系图: 直接来看代码: [java] view plaincopypublic class Tr ...

  5. KVM克隆 快照

    原创博文安装配置KVM http://www.cnblogs.com/elvi/p/7718574.htmlweb管理kvm http://www.cnblogs.com/elvi/p/7718582 ...

  6. MySQL学习——基本命令(1)

    MySQL添加新用户.为用户创建数据库.为新用户分配权限 参考博客http://blog.csdn.net/u013216667/article/details/70158452 一.登录MySQL ...

  7. Netty之粘包分包

    粘包现象 客户端在一个for循环内连续发送1000个hello给Netty服务器端, Socket socket = new Socket("127.0.0.1", 10101); ...

  8. Android数据绑定技术一,企业级开发

    PS:数据绑定,顾名思义是数据与一些控件或者用户账号等绑定,这样用的好处是便于管理.代码清晰,量少. 首先要了解什么是数据绑定? 为什么要用数据绑定? 怎么用数据绑定? 语法的使用 简单例子,数据绑定 ...

  9. 毕达哥拉斯树(pythagorasTree)原理解析及canvas动画实现

    以前就看到了这个东西,由于太忙了最近才有时间来实现这个; 该文章适合有一定 canvas 基础的人阅读; 首先说说他的原理: The construction of the Pythagoras tr ...

  10. Springboot 使用 JSR 303 对 Controller 控制层校验及 Service 服务层 AOP 校验,使用消息资源文件对消息国际化

    导包和配置 导入 JSR 303 的包.hibernate valid 的包 <dependency> <groupId>org.hibernate.validator< ...