피연산자 평가 순서

a + fun(a)에서 a와 fun(a) 가운데 무엇을 먼저 계산할까?

피연산자의 값

값을 얻는 방법은 네 가지

변수, 상수, 괄호 식은 값을 꺼내거나 계산하면 끝입니다. 함수 호출은 다릅니다. 함수를 실행해야 값이 나오는데, 함수는 실행되는 동안 다른 일도 할 수 있습니다.

기계어는 1강에서 본, 하드웨어가 알아듣는 말입니다.

함수적 부작용

함수가 밖의 변수를 바꿉니다

함수가 자기 밖에 있는 변수를 바꾸는 것을 함수적 부작용(functional side effect)이라고 합니다. 그림의 fun은 10을 돌려주면서 a를 20으로 바꿉니다.

C에서 &a는 a가 든 메모리 칸의 위치를 넘긴다는 뜻이라, fun이 a를 바꿀 수 있습니다. fun이 하는 일은 예시입니다.

왼쪽 먼저

a부터 꺼내면 20

먼저 왼쪽 피연산자 a의 값 10을 꺼냅니다. 그다음 fun이 a를 20으로 바꾸지만, 이미 꺼낸 10은 그대로입니다. 10 + 10이라 b는 20입니다.

fun은 앞 장과 같습니다. 10을 돌려주고 a를 20으로 바꿉니다.

오른쪽 먼저

fun부터 부르면 30

이번에는 fun을 먼저 부릅니다. a가 20으로 바뀐 뒤에 a를 꺼내므로 20이 나옵니다. 20 + 10이라 b는 30입니다. 코드는 한 글자도 바뀌지 않았는데 답이 달라졌습니다.

해결 ① 부작용 금지

함수가 밖을 못 바꾸게 합니다

언어가 함수적 부작용을 아예 금지하는 방법입니다. 함수가 양방향 매개변수(two-way parameter)도 비지역 변수(non-local variable)도 쓰지 못합니다. 부작용은 사라지지만 함수의 쓸모가 줄어듭니다.

매개변수는 함수가 값을 넘겨받는 변수입니다. 앞에서 본 &a가 양방향 매개변수의 예입니다.

해결 ② 순서 고정

평가 순서를 하나로 못박습니다

피연산자를 평가하는 순서를 언어가 정해 두는 방법입니다. 자바는 왼쪽에서 오른쪽으로 평가하도록 요구합니다. 대신 컴파일러가 순서를 자유롭게 바꾸지 못해 최적화 일부가 막힙니다.

컴파일러는 소스를 기계어로 번역하는 프로그램이고, 최적화는 군더더기를 덜어 내는 일입니다.

다음 편

부작용이 없으면 무엇이 좋을까요. 그 성질에 이름이 있습니다

4편같은 식은 늘 같은 값일까? 6강 목록