官术网_书友最值得收藏!

Referential transparency

To understand referential transparency, let's first consider the following description:

Let me tell you a bit about India's capital, New Delhi. The Indian capital houses the Indian Parliament. The Indian capital is also home to Gali Paranthe Wali, where you get to eat the famous parathas.

We can also say the following instead:

Let me tell you a bit about India's capital, New Delhi. New Delhi houses the Indian Parliament. New Delhi is also home to Gali Paranthe Wali, where you get to eat the famous parathas.

Here, we substituted New Delhi with the Indian capital, but the meaning did not change. This is how we would generally express ourselves.

The description is referentially transparent with the following commands:

scala> def f1(x: Int, y: Int) = x * y
f1: (x: Int, y: Int)Int

scala> def f(x: Int, y: Int, p: Int, q: Int)= x * y + p * q
f: (x: Int, y: Int, p: Int, q: Int)Int

scala> f(2, 3, 4, 5)
res0: Int = 26

If we rewrite the f method as follows, the meaning won't change:

scala> def f(x: Int, y: Int, p: Int, q: Int)= f1(x, y) + f1(p, q)
f: (x: Int, y: Int, p: Int, q: Int)Int

The f1 method just depends upon its arguments, that is, it is pure.

Which method is not referentially transparent? Before we look at an example, let's look at Scala's ListBuffer function:

scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer

The ListBuffer is a mutable collection. You can append a value to the buffer and modify it in place:

scala> val v = ListBuffer.empty[String]
v: scala.collection.mutable.ListBuffer[String] = ListBuffer()

scala> v += "hello"
res10: v.type = ListBuffer(hello)

scala> v
res11: scala.collection.mutable.ListBuffer[String] = ListBuffer(hello)

scala> v += "world"
res12: v.type = ListBuffer(hello, world)

scala> v
res13: scala.collection.mutable.ListBuffer[String] = ListBuffer(hello, world)

Armed with this knowledge, let's now look at the following command:

scala> val lb = ListBuffer(1, 2)
lb: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2)

scala> val x = lb += 9
x: lb.type = ListBuffer(1, 2, 9)
scala> println(x.mkString("-"))
1-2-9
scala> println(x.mkString("-"))
1-2-9

However, by substituting x with the expression (lb += 9), we get the following:

scala> println((lb += 9).mkString("-")) // 1 
1-2-9-9
scala> println((lb += 9).mkString("-")) // 2
1-2-9-9-9

This substitution gave us different results. The += method of ListBuffer is not a pure function as there is a side effect that occurred. The value of the lb variable at 1 and 2 is not the same.

主站蜘蛛池模板: 德惠市| 舟曲县| 汕尾市| 临江市| 井研县| 宝坻区| 桦南县| 黎川县| 岳西县| 连城县| 无锡市| 松原市| 怀仁县| 兰坪| 松桃| 砚山县| 惠东县| 德化县| 广南县| 黄龙县| 庆云县| 大城县| 三台县| 乌拉特中旗| 丹东市| 晴隆县| 禹城市| 环江| 岳西县| 志丹县| 盐山县| 定南县| 云南省| 新津县| 青龙| 咸丰县| 兰州市| 永济市| 五大连池市| 合作市| 额尔古纳市|