异常和引用透明度
Exceptions and referential transparency
正在阅读 "Functional Programming in Scala",我对异常不具有引用透明性的部分感到有些困惑。
给出的例子是
def failingFn(i: Int): Int = {
val y: Int = throw new Exception("fail!")
try {
val x = 42 + 5
x + y
}
catch { case e: Exception => 43 }
}
所以书中给出的论点是 y
不是引用透明的,因为如果我们将它替换到 try
块的正文中,我们得到的结果与仅 [=26] 不同=] 直接函数。这对我来说没有任何意义,因为整个函数一开始是非终止的,那么说函数体内的值不是引用透明的有什么意义呢?在我看来天真的替换如下
def failingFn(i: Int): Int = {
val y: Int = throw new Exception("fail!")
try {
val x = 42 + 5
x + ((throw new Exception("fail!")): Int)
}
catch { case e: Exception => 43 }
}
并且仍然失败并出现相同的异常。
此外,y
本身是一个非值(它不能直接求值)那么讨论此类表达式的引用透明性有什么意义呢?我怀疑这里有某种诡计,所以我的推理到底哪里不正确?
书中的要点是,如果它确实是引用透明的,那么您可以完全删除 y
变量并在 try/catch
中替换它,最后得到不同的语义。
所以,要点是,在异常情况下,异常的评估点很重要。
也许您可以争辩说这两个程序在语义上并不相同,因为计算的位置才是真正重要的。如果你让y
lazy
,那么结果不会改变。
正在阅读 "Functional Programming in Scala",我对异常不具有引用透明性的部分感到有些困惑。
给出的例子是
def failingFn(i: Int): Int = {
val y: Int = throw new Exception("fail!")
try {
val x = 42 + 5
x + y
}
catch { case e: Exception => 43 }
}
所以书中给出的论点是 y
不是引用透明的,因为如果我们将它替换到 try
块的正文中,我们得到的结果与仅 [=26] 不同=] 直接函数。这对我来说没有任何意义,因为整个函数一开始是非终止的,那么说函数体内的值不是引用透明的有什么意义呢?在我看来天真的替换如下
def failingFn(i: Int): Int = {
val y: Int = throw new Exception("fail!")
try {
val x = 42 + 5
x + ((throw new Exception("fail!")): Int)
}
catch { case e: Exception => 43 }
}
并且仍然失败并出现相同的异常。
此外,y
本身是一个非值(它不能直接求值)那么讨论此类表达式的引用透明性有什么意义呢?我怀疑这里有某种诡计,所以我的推理到底哪里不正确?
书中的要点是,如果它确实是引用透明的,那么您可以完全删除 y
变量并在 try/catch
中替换它,最后得到不同的语义。
所以,要点是,在异常情况下,异常的评估点很重要。
也许您可以争辩说这两个程序在语义上并不相同,因为计算的位置才是真正重要的。如果你让y
lazy
,那么结果不会改变。