例外和参考透明度

时间:2015-03-11 16:51:28

标签: scala functional-programming referential-transparency

阅读" 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块中的主体,我们会得到与直接运行函数不同的结果。这对我没有任何意义,因为整个函数从一开始就是非终止的,那么说函数体内的值不是引用透明的又是什么意思呢?我心中的天真替代如下

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本身是一个非值(它不能直接被评估为一个值),那么谈论这些表达式的引用透明度有什么意义呢?我怀疑这里有什么样的手法,所以我的推理到底是不正确的?

1 个答案:

答案 0 :(得分:7)

本书中提到的一点是,如果它真的是引用透明的,那么你可以完全删除y变量并将其替换为try/catch内部,并最终得到不同的语义

因此,要点是,在例外的情况下,异常的评估点很重要。

也许你可以争辩说这两个程序在语义上并不相同,因为评估的位置在这里真正重要。如果您制作y lazy,则结果不会更改。