함수 호출
코딩을 하다보면 이래저래 함수를 호출하기 마련이다.
이 함수는 보통 argument라 불리는(경우에 따라서는 parameter라 불리는)입력 값들을 갖는다.
이때 함수에 입력 값을 넘겨주는 방법으로 보통 call-by-value, call-by-reference를 배웠다.
그리고 우리는 이미 변수를 선언하고 값을 할당하면 heap 영역에 해당 변수를 위한 메모리 공간이 생기며 그곳에 값이 저장되는 것을 알고 있다.
복습
Call by value
직역한 ‘값에 의한 호출’로 이해하면 된다.
함수에 입력 값을 넘겨줄 때 변수의 값을 바로 넘겨주고 이 값은 새로운 공간에 할당되어 사용된다.
- 변수 a, b에는 각각 100, 200 의 값이 할당되어 있다.
- 함수 f는 입력 값 두 개인 x, y를 가지며 각 값마다 1씩 더해주고 아무 것도 리턴하지 않는다.
- a, b를 출력하고 함수 f(a,b)를 실행한 후에 다시 한번 a, b를 출력한다.
출력한 결과는 다음과 같다.
함수 호출 후 : 100, 200
함수 호출 전 : 100, 200
함수내에서 값을 더해주었지만 a, b가 아닌 100, 200 이라는 값을 넘겨준 것이기때문에 a, b는 아무런 변화가 없다.
Call by reference
변수의 값이 아닌 변수가 사용중인 메모리 공간의 주소를 넘겨주는 방식이다.
따라서 위 값에 의한 호출 시나리오를 실행하면 출력 결과는 다음과 같다.
함수 호출 후 : 100, 200
함수 호출 전 : 101, 201
해당 변수가 사용중인 공간에 대해 작업을 진행하였으므로 당연히 함수 호출 후에도 그 작업 결과는 남아 있게 된다.
Call by name
갑자기 생소한게 튀어 나왔다. 처음 이 용어를 들었을 땐 오타정도인줄 알았다.
오타라고 친절하게 call by reference라고 정정해주기 까지 했다. 하지만 내가 무식한거였다.
위의 두개와 마찬가지로 함수 호출시 값을 넘겨주는 방식의 용어이다.
이 용어는 사실 함수를 인자로 넘겨줄 수 있는 언어에서만 사용한다.
이것은 함수에서 입력 값으로 받은 값에 대해 해당 값이 쓰인 라인을 실행할때 평가하는 것이다.
다음과 같이 특정 함수를 함수의 인자로 넘겨준다고 생각해보자.
function hou() {
print 'hi'
}
function call(x) {
print 'call'
x();
}
call(hou());
이때 일반적으로 생각하는 출력 순서는 다음과 같다.
hi
call
하지만 call by name의 형태로 인자를 넘겨준다면 다음과 같다.
call
hi
call 문자열이 먼저 출력된다. 인자로 넘겨준 함수 hou는 call함수내에서 직접 사용이 되는 라인이 불리기 전까지 실행되지 않고 해당 라인에 불리는 시점에 호출된다.
내가 함수형 언어에 대해 아직 접해보지 않아 동작하는 코드에 대한 예제는 만들지 못하였다.
References
- https://www.tutorialspoint.com/cprogramming/c_function_call_by_value.htm
- https://medium.com/@OutOfBedlam/scala-call-by-value-vs-call-by-name-734a79c75ccb