subRoutine에서 참조를 보내면 참조가 퍼져나간다. 이를 끊어내기 위해 새로운 값으로 참조를 끊어낸다 (인자도 위험하다.) ⇒ 안전하게 만들자
함수의 리턴 포인트를 변경하여 꼬리 물기 최적화를 한다. 이때 포인트는 루틴의 리턴 시점에 메모리 해제가 가능해야함.
const sum = v => v + (v > 1 ? sum(v - 1) : 0);
sum(3);
모든 연산자는 꼬리 물기 최적화를 방해함.
모든 연산자(&&, ||, 삼항연산자 제외)는 스택 구조를 이용해. ⇒ 로컬 변수를 인자로 넘긴다.
const sum = (v, prev = 0) => {
prev += v;
return (v > 1 ? sum(v - 1, prev) : prev);
}
sum(3);
꼬리물기 최적화의 방법 1) 스택메모리로 사용할 데이터를 인자로 넘긴다. (중요하다.)
🌷재귀성 문제는 꼬리물기 최적화로 생각하자.
prev
는 aggrigation, 즉 외재화 할 수 있는 변수
const sum = (v) => {
let prev = 0;
while(v > 1) {
prev += v;
v--;
}
return prev;
}
loop ↔ 꼬리 물기 최적화 기계적 변경 필요
기존 언어들은 함수를 문으로 본다.
하지만 람다는 함수를 값으로 본다. 자바스크립트도 이와 같은 방식이다.