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

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.

主站蜘蛛池模板: 凯里市| 隆林| 黑河市| 泸州市| 惠州市| 马山县| 上思县| 孙吴县| 宁远县| 松江区| 曲阜市| 梅河口市| 礼泉县| 江油市| 建昌县| 故城县| 东宁县| 景德镇市| 西乌珠穆沁旗| 依安县| 南丹县| 七台河市| 诸城市| 德昌县| 黎城县| 池州市| 赫章县| 伊吾县| 刚察县| 乌什县| 西乡县| 淅川县| 民权县| 西乌珠穆沁旗| 宁陵县| 如皋市| 广丰县| 松阳县| 漯河市| 吉安县| 浦城县|