scala - 我对带有可变类的 "referential transparency"的理解是否正确?

标签 scala functional-programming referential-transparency

从《Functional programming in scala》一书中看到表达式的“引用透明”的定义:

An expression e is referentially transparent if, for all programs p, all occurrences of e in p can be replaced by the result of evaluating e without affecting the meaning of p.

我有一些代码示例,我不确定它们是否是引用透明的。

我将在示例中使用 scala.collection.mutable.StringBuilder,这是一个可变类

1.

val x = new StringBuilder("Hello")

println(x.length)
println(x.length)

假设这里的代码是使用x的完整代码。

我可以说表达式 x 是引用透明表达式吗?

如果我用它的值 new StringBuilder("Hello") 更改所有 x,程序的可观察行为不会改变:

val x = new StringBuilder("Hello")

println(new StringBuilder("Hello").length)
println(new StringBuilder("Hello").length)

2.

val x = new StringBuilder("Hello")
val y = x.append("aaa")

假设这里的代码是使用xy的完整代码。

我能说 y 是引用透明的吗,因为它根本没有在程序中使用?

3.

def getTheClassName(n:Int):String = {
  val x = new StringBuilder("hello")
  for(int i=0;i<n;i++) {
    x.append("world")
  }
  return x.getClass.getName
}

我可以说 x 是引用透明的吗?因为不管我怎么替换它的值,返回值都不会改变。

PS:可能主要问题是我不明白for all programs p是什么意思,是指现有的完整代码吗?或者可以添加任何可能的代码?

最佳答案

这意味着对于任何可能的程序p你可能会写包含那个表达。正确地,这应该针对一种语言或一组可能的程序来定义。所以你的 x在唯一有效的程序是您编写的语言中,是引用透明的。你的y在不允许调用 .append 的 Scala 子集中引用透明 StringBuilder。但这些都不是特别有趣的语言。

大多数时候,当人们谈论“引用透明”表达式时,他们(隐含地)指的是像 Scalazzi safe subset of Scala 这样的东西。 ,这足以表达(所有?)有用的 Scala 程序,但足够安全以进行推理。因为当然如果你被允许打电话System.identityHashCode() ,大多数所谓的“引用透明”表达式实际上不是。

当然,最重要的定义是操作定义;什么是“参照透明”最终取决于你想用它做什么。一个重要的用例是编译器/库优化:我们不希望编译器执行您在示例 1 中给出的替换,因为对于大多数程序而言,这种“优化”会改变程序的含义。但我们很高兴编译器通过内联不可变常量来优化我们的程序,因为我们的程序“不应该”依赖于 identityHashCode 的内容。一个特定的常数是。

关于scala - 我对带有可变类的 "referential transparency"的理解是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27032779/

相关文章:

javascript - 如何将此递归函数转换为迭代函数?

functional-programming - 如何在 Elm 0.17/0.18 中获取当前时间?

scala - 异常(exception)和参照透明度

scala - 如何避免在模式匹配防护中显式调用 .isDefinedAt()

scala - 我可以使用虚拟类(class)做什么?

haskell - 为什么这两段代码的行为不同?

haskell - Haskell 中的随机数采样序列

functional-programming - 什么是参照透明度?

scala - Akka 。如何知道所有 child Actor 都完成了他们的工作

scala - 在 ScalaTest 中断言案例类