- Scala Functional Programming Patterns
- Atul S. Khot
- 408字
- 2021-07-30 09:44:22
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.
- Functional Python Programming
- Learn Blockchain Programming with JavaScript
- AngularJS Web Application Development Blueprints
- 編寫整潔的Python代碼(第2版)
- Java:Data Science Made Easy
- 老“碼”識途
- Julia高性能科學計算(第2版)
- Learning Material Design
- SQL Server 2016 從入門到實戰(視頻教學版)
- Vue.js光速入門及企業項目開發實戰
- Oracle 12c從入門到精通(視頻教學超值版)
- C# 7.1 and .NET Core 2.0:Modern Cross-Platform Development(Third Edition)
- Apache Solr for Indexing Data
- 鋁合金陽極氧化與表面處理技術(第三版)
- 深入理解C++11:C++11新特性解析與應用