이 함수 꼬리 호출은, 지금까지 내가 해봤던 언어(라고 해봤자 C와 C++, PHP 밖에 없다)에서는 들어보지 못한 개념이다. (책에선 자동 꼬리 호출 이라하고 직역하면, 적절한 꼬리 호출 이라 하지만, 함수에 관련된 것이라 함수라고 하는게 더 좋을것 같기도 하다.)


함수 꼬리 호출은 무엇 인가?

함수A의 호출 후 함수A 내부에서 다른 함수B를 호출 하게 될 경우, A는 B의 꼬리이며, A는 꼬리 호출 된다고 할 수 있고, A는 B의 꼬리라고 할 수 있다. 즉 A는 B의 꼬리 함수이며, B는 꼬리 함수A의 호출 함수라 부를 수 있다.


이것이 왜 중요한가?

루아에선 이 함수 꼬리 호출이 특별한 조건이 만족하면, 스택 버퍼를 더 늘리지 않으면서 꼬리 함수를 잘라버려 주기 때문에 중요하다. 다시 말하면 함수 A를 잘라 준다.


그 조건은 무엇인가?

코드로 보자.

f() 의 내부에서 return g( x ) 라고 되어 있는 것을 확인 할 수 있는데, 이렇게 f()의 내부에 아무것도 안하고 바로 return g(x) 이라고 하면 된다.


이것이 어디에 유용한가?

이것을 응용하면, 내부 연산이 간단하면서 다른 함수를 호출해야만 할 때, 그 다른 함수의 매개변수를 계산식으로 만들어서 넣어 주면 된다. 다음 코드를 보자.

이렇게 g의 매개변수에 전달 되는 것을 식으로 넘기게 되면, 루아가 알아서 꼬리함수를 제거하게 될 것이다.


관련 링크

http://www.lua.org/pil/6.3.html


총평

C나 C++ 에서도 해주지 않을까? 란 생각으로 테스트 해보니, 재귀 함수 호출을 하여도 메모리가 늘지 않는다; 그래서 int형 1024개를 만들면서도 했는데, 메모리가 늘지 않는다. 계산식을 넣었는데도 메모리가 늘지 않는다. C/C++ 도 적절히 스택을 정리해 주는 것을 확인 할 수 있었다.

스택을 정리하지 못하게 하는 가장 나쁜 코드는 g( x ) + 1 과 같은 것들일 것이다. 이런 류는 C/C++ 이나 lua 나 조심해서 해야 될 것 같다.



신고
posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요