Estoy leyendo la programación del libro en scala, y se dice:
... en este caso, su efecto secundario es imprimir en la secuencia de salida estándar.
y no veo dónde está el efecto secundario, ya que, para la misma entrada, println imprimirá la misma salida (creo)
ACTUALIZAR,
por ejemplo, cada vez que llamemos:
println(5)
imprimirá 5 , ¡no veo un caso en el que llamar println(5)
imprima un valor diferente a 5!
scala
functional-programming
pure-function
un nombre
fuente
fuente
println
es una función determinista pero para ser pura también debe ser RT.Respuestas:
Puede saber si una expresión tiene un efecto secundario reemplazando la expresión con su resultado. Si el programa cambia de significado , hay un efecto secundario. Por ejemplo,
es un programa diferente para
Es decir, un efecto secundario es cualquier efecto observable que no está codificado en el resultado de evaluar una expresión. Aquí el resultado es
()
, pero no hay nada en ese valor que codifique el hecho de que ahora 5 ha aparecido en algún lugar de su pantalla.fuente
val a = println("hello"); val b = (a, a)
debería ser lo mismo queval b = (pritnln("hello"), println("hello"))
.println(5)
y()
. ¿O quisiste decir la última oración?x = 1
yx = 1; x = 1; x = 1
?Considere la siguiente analogía
Aquí
myprintln
es impuro porque, además del valor de retorno()
, también muta la variable no localout
como efecto secundario. Ahora imaginaout
que la corriente vainillaprintln
muta.fuente
()
, también muta el estado no local enSystem.out
.El efecto secundario está en el estado de la computadora. Cada vez que llama
println()
el estado de los cambios de memoria para mostrar el valor dado al terminal. O, más generalmente, se cambia el estado del flujo de salida estándar.fuente
Ya se dieron buenas respuestas a esta pregunta, pero permítanme agregar mis dos centavos.
Si observará la
println
función interna esencialmente, es lo mismo quejava.lang.System.out.println()
, por lo tanto, cuando invoca elprintln
método de biblioteca estándar de Scala debajo del capó, invoca el métodoprintln
en laPrintStream
instancia del objeto que se declara como campoout
en laSystem
clase (o más precisamenteoutVar
en elConsole
objeto), que cambia su estado interno . Esto puede considerarse como otra explicación de por quéprintln
es una función impura.¡Espero que esto ayude!
fuente
Tiene que ver con el concepto de transparencia referencial . Una expresión es referencialmente transparente si puede sustituirla con su resultado evaluado sin cambiar el programa .
Cuando una expresión no es referencialmente transparente, decimos que tiene efectos secundarios .
mientras
Puede encontrar una explicación más detallada aquí: https://typelevel.org/blog/2017/05/02/io-monad-for-cats.html
fuente
f(println("effect"), println("effect"))
va a imprimir dos veces en "efecto" de consola mientrasval x = println("effect");f(x,x)
que va a imprimir una vez.