为什么 println 被认为是一个不纯的函数?

aNa*_*ame 10 functional-programming scala pure-function

我正在阅读 Scala 编程这本书,据说:

...在这种情况下,它的副作用是打印到标准输出流。

我没有看到副作用在哪里,因为对于相同的输入, println 将打印相同的输出(我认为)
UPDATE
例如,每当我们调用:

println(5)
Run Code Online (Sandbox Code Playgroud)

它将打印5,我没有看到调用println(5)会打印 5 以外的值的情况!

Joe*_*ley 6

您可以通过用结果替换表达式来判断表达式是否有副作用。如果程序改变了含义,就会产生副作用。例如,

println(5)
Run Code Online (Sandbox Code Playgroud)

是一个不同的程序

()
Run Code Online (Sandbox Code Playgroud)

也就是说,副作用是任何未在表达式计算结果中编码的可观察效果。这里的结果是(),但该值中没有任何内容可以对 5 现在出现在屏幕上的某个位置这一事实进行编码。

  • 实际上,这不是“副作用”的一个好的定义 - 副作用可以定义为任何破坏引用透明度的东西。您试图在这里展示的是 RT,但您的示例是错误的。因为多次执行某件事应该多次做同样的事情 - 相反,`val a = println("hello"); val b = (a, a)` 应该与 `val b = (pritnln("hello"), println("hello"))` 相同。 (6认同)
  • 我想说这是错误的,因为某些东西完全有可能产生副作用并且是幂等的,因此重复它不会改变效果。例如对可变变量的赋值;如何区分“x = 1”和“x = 1”;x = 1; x = 1`? (5认同)

Cod*_*ice 6

副作用在于计算机的状态。每次调用时,println()内存状态都会发生变化,以便将给定值显示到终端。或者更一般地说,标准输出流的状态发生了变化。

  • 这样,任何函数、操作......都会是不纯粹的,因为它改变了内存cpu的状态......, (2认同)

Mar*_*lic 5

考虑以下类比

var out: String = ""
def myprintln(s: String) = {
  out += s // this non-local mutation makes me impure
  ()
}
Run Code Online (Sandbox Code Playgroud)

myprintln是不纯的,因为除了返回值之外,()它还会将非局部变量out作为副作用进行变异。现在想象out成为流香草println变异。