[scala] println이 불순한 기능으로 간주되는 이유는 무엇입니까?

스칼라에서 책 프로그래밍을 읽고 있는데 다음과 같습니다.

…이 경우 부작용은 표준 출력 스트림으로 인쇄됩니다.

같은 입력,에 println은 동일한 출력 (내가 생각하는) 인쇄됩니다 이후, 부작용이다 나는 표시되지 않습니다

UPDATE
예를 들어 우리가 전화를 언제든지 :

println(5)

그것은 인쇄 할 5 내가 요구하는 경우 표시되지 않습니다, println(5)5 이외의 값을 출력됩니다!



답변

표현식을 결과로 바꾸면 표현식에 부작용이 있는지 알 수 있습니다. 프로그램의 의미 가 변경되면 부작용이 있습니다. 예를 들어

println(5)

다른 프로그램입니다

()

즉, 부작용은 표현식을 평가 한 결과로 인코딩되지 않은 관찰 가능한 효과입니다. 결과는입니다 만 (), 화면에 어딘가에 5가 나타났음을 나타내는 값에는 아무것도 없습니다.


답변

다음 비유를 고려하십시오

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

여기 myprintln불순한이므로 값을 반환 옆 ()그것은 또한 변이 비 로컬 변수 out부작용있다. 이제 out스트림 바닐라 println돌연변이가 있다고 상상해보십시오 .


답변

부작용은 컴퓨터 상태입니다. println()주어진 값을 터미널에 표시하기 위해 메모리 상태가 변경 될 때마다 변경됩니다. 또는보다 일반적으로 표준 출력 스트림의 상태가 변경됩니다.


답변

이 질문에 대한 좋은 답변이 이미 제공되었지만 2 센트를 추가하겠습니다.

당신이 안에 보면됩니다 println기능 본질적으로는 동일합니다 java.lang.System.out.println()– 그래서 때를 스칼라의 표준 라이브러리 호출 println이 방법을 호출 후드 아래 방법 printlnPrintStream필드로 선언 된 객체 인스턴스 out에서 System(보다 정확하게 또는 클래스 outVar에서 Console그 내부 상태를 변경 개체), . 이것은 왜 println불순한 기능 인지 에 대한 또 다른 설명으로 간주 될 수 있습니다 .

도움이 되었기를 바랍니다!


답변

그것은 참조 투명성 의 개념과 관련이 있습니다. 프로그램을 변경하지 않고 평가 결과로 대체 할 수 있으면 표현식은 참조 용으로 투명합니다 .

표현식이 참조 적으로 투명하지 않으면 부작용 이 있다고 말합니다 .

f(println("effect"), println("effect"))
// isn't really equivalent to!
val x = println("effect")
f(x, x)

동안

import cats.effect.IO

def printlnIO(line: String): IO[Unit] = IO(println(line))

f(printlnIO("effect"), printlnIO("effect"))
// is equivalent to
val x = printlnIO("effect")
f(x, x)

https://typelevel.org/blog/2017/05/02/io-monad-for-cats.html에서 자세한 설명을 찾을 수 있습니다.


답변