SweatBuffer`s Blog

Functional programming in Scala(一)

#Scala/Chapter1#

What is a pure function

Pure function is one that lacks side effects.
what is side effects?

  • 修改一个变量
  • 当场修改一个数据结构
  • 对对象设置领域
  • 抛出异常和处理error
  • 命令提示符中打印,读取用户输入
  • 读写文件
  • 画图
  • 连接server等~~

用一句话说 一个函数除了根据我们的输入值计算结果之外不做任何我们可以观察得到的行为,那么可以基本看为纯粹函数,prue function。

Referential Transparency(RT)

referential transparency 也叫 引用性透明: referential Transparency不只是 function的性质,也是 expressions的性质:在任何的程序里面 表达式可以在不改变程序语义的情况下,用结果值,result 来替换表达式。

Referential transparency and purity

An expression e is referential transparent if , for all programs p, all occurrences of e in pcan be replaced by the result of evaluating e without affecting the meaning of p.
A function f is pure if the expression f(x)is referentially transparent for all referentially transparent x.

Substitution model

Referential transparency forces the invariant that everything a function does is represented by the ~value~ that it returns, according to the result type of the functions.
This constraint enables a simple and natural mode of reasoning about program evaluation called the ~substitution model~

在这样的规则下,我们的计算过程就是想是解代数方程。我们扩张表达式的所有的部分然后用他们的 参考对象 替换所有的变量,然后分解到最简式子。换句话说 RT 允许 方程式推理(equational reasoning )

关于RT的个人的想法:

RT叫 referential transparency 引用性透明,相比较C 这种语言来说有着很大的不同。scala中 对一个变量调用他的一些方法,产生了一个新的结果,这个结果会给予一个新的空间,新的变量名字,之前引用的变量不发生任何变化。
为啥这样设计,因为要支持函数式编程,很符合递归的概念。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
scala> val x= "Hello,world"
x: String = Hello,world
scala> val r1 = x.reverse
r1: String = dlrow,olleH
scala> var r2 = x.reverse
r2: String = dlrow,olleH
scala> val r1 = "Hello,world".reverse
r1: String = dlrow,olleH
scala> val r2 = "Hello,world".reverse
r2: String = dlrow,olleH

x 是 String 对象,reverse 是 String 类的 成员方法
这个例子就是 x 调用了 reverse之后 并没有改变x自身的值,所以再次调用reverse方法 还是一样的结果。就完全可以用 x 的值”Hello,world”来替代之前式子中的x。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
scala> val x = new StringBuilder("Hello")
x: StringBuilder = Hello
scala> val y = x.append(",world")
y: StringBuilder = Hello,world
scala> val r1 = y.toString
r1: String = Hello,world
scala> val r2 = y.toString
r2: String = Hello,world
scala> val r3 = x.append(",world").toString
r3: String = Hello,world,world
scala> x
res102: StringBuilder = Hello,world,world

这里的x 是 Stringbuilder 对象 , append 是 Stringbuilder 类的 成员方法。
这里 x 调用了一次 append 方法之后,自身的值改变了,所以在第二次调用append 的时候 变成了 Hello,world,world。而 String 对象的 toString方法,没有啥变化,调用了两次也没啥问题。所以Stringbuilder.append不是一个pure function 不是存粹方法。所以side effect 使得程序推理编的很困难。

SweatBuffer wechat
扫描二维码