부수효과 (전산학)
위키백과 ― 우리 모두의 백과사전.
전산학에서 함수가 결과값 이외에 다른 상태를 변경시킬 때 부수효과가 있다고 말한다. 예를 들어, 함수가 전역변수나 정적변수를 수정하거나, 인자로 넘어온 것들 중 하나를 변경하거나 화면이나 파일에 데이터를 쓰거나, 다른 부수효과가 있는 함수에서 데이터를 읽어오는 경우가 있다. 부수효과는 프로그램의 동작을 이해하기 어렵게 한다.
명령형 프로그래밍은 부수효과를 사용하여 프로그램이 동작하게 하는 것으로 알려져 있다. 함수형 프로그래밍은 부수효과를 최소화하는 것으로 알려져 있다.
[편집] 참조 투명성
부수효과를 사용하는 함수는 참조에 불투명(영어: referentially opaque)하고 그렇지 않은 함수는 참조에 투명(영어: referentially transparent)한 경우가 많다. 참조에 투명한 함수는 같은 인자를 주면 항상 같은 결과값을 돌려 주는 함수이다. 또 다른 용어로 참조에 투명한 함수는 결정 함수(영어: deterministic function)이다.
부수효과는 없지만 참조에 불투명한 함수도 있다. 예를 들어서 외부 세계를 측정하는 어떤 함수는 참조에 불투명하다. 예를 들어, 현재 시간을 컴퓨터의 시계에서 읽어오는 컴퓨터 함수는 같은 인자를 넘겨주더라도 다른 결과값을 돌려주어야 한다. 이것이 전역 상태를 전혀 바꾸지 않지만, 시간이라고 불리는 전역 상태가 변하여 영향을 받기 때문이다.
[편집] 예제
예제로 두 함수를 쓰기로 하자. 하나는 참조에 불투명하고 다른 하나는 참조에 투명하다.
globalValue = 0; integer function rq(integer x) begin globalValue = globalValue + 1; return x + globalValue; end
integer function rt(integer x) begin return x + 1; end
이제 rt
는 참조에 투명하다. 왜냐하면 x
의 값이 변하지 않는 이상 rt(x) = rt(x)
이기 때문이다. 예를 들어, rt(6) = rt(6) = 7, rt(4) = rt(3+1) = 5
등이 성립한다. 그러나 rq
에 대해서는 그런 말을 할 수 없는데 이것이 전역 변수를 변경하기 때문이다.
다음과 같은 코드를 보면 참조에 불투명함의 단점을 알 수 있다.
integer p = rq(x) + rq(y) * (rq(x) - rq(x));
오른쪽 부분을 계산하여 정리하면 이렇게 될 것이다.
integer p = rq(x) + rq(y) * (0) = integer p = rq(x) + 0 = integer p = rq(x);
그러나 이것은 rq
에 대해서는 성립하지 않는데 rq(x)
는 rq(x)
와 같지 않기 때문이다. rq
의 결과값은 전역값에 따라 차이가 있으며 그 전역값이 전달되는 것이 아니라 변경되고 있기 때문이다. 이것은 어떤 식에서 같은 식을 빼면 0이 된다는 상식을 깨뜨린다.
그러나 rt
에 대해서는 이런 것들이 통할 것인데, 이것은 참조에 투명한 함수이기 때문이다.
[편집] 부수효과의 단점
부수효과는 프로그램의 버그가 발생하기 쉽게 한다. 프로그램을 테스트할때에는 발생하지 않았던 예외 상황들이 프로그램을 사용하면서 발견되지만 항상 일어나지 않는 예외 상황이 일어나서 버그를 고치기 어렵게 하기도 한다.
프로그램의 결과값을 계산하는 것 이외에 다른 상태를 변경시키므로 프로그램의 순서에 따라서 다른 결과가 나온다. 이것은 프로그램의 최적화와 느긋한 계산법을 하기에 좋지 않은 특성이며, 각각의 의존성을 심화시킨다. 심지어 최적화를 한 경우 실행 결과가 틀려질 가능성도 있다. 실행 순서를 무시할 수 없기 때문에 프로그래머는 실행 순서를 정해주어야 하는 부담이 있다.
마지막으로 상식에서 통하는 방법으로 표현식을 값으로 대체하거나 값 대신 변수로 대체하는 일을 할 수 없게 되며 수학적으로 다루기 어렵게 된다.