올바른 꼬리 호출과 재귀

꼬리 적용은 명시적 트램펄린에서 현재 평가기 프레임을 교체하므로 자기·상호 꼬리 재귀가 논리 연속을 늘리지 않습니다.

언제 필요한가요?

루프를 재귀로 쓰는 것이 자연스러울 때 꼬리 호출이 중요합니다. 재귀 호출이 마지막 동작이면 리스펙스는 연속을 하나 더 쌓지 않고 현재 연속을 교체할 수 있습니다.

실행으로 확인하기

LISPEX
(let loop ((n 10000) (acc 0)) (if (= n 0) acc (loop (- n 1) (+ acc 1))))

관측 결과

OUTPUT
10000

예제 읽기

이름 있는 letloop를 만듭니다. 각 분기는 acc를 반환하거나 더 작은 n과 새 acc로 즉시 loop를 호출합니다. 호출 뒤에 남은 덧셈이 없으므로 1만 번도 하나의 논리적 루프로 끝납니다.

이 순서로 생각하세요

  • 꼬리 위치에는 마지막 본문, 두 if 가지, 정규화된 cond·case, 마지막 and·or, do, call-with-values, apply가 포함됩니다.
  • 올바른 꼬리 동작은 연속 깊이에 관한 것이며 동일한 실행 시간이나 무제한 실행을 뜻하지 않습니다.
  • 꼬리 재귀 프로그램에도 결정적이며 프로필별인 자원 한도가 적용됩니다.

빠르게 고르기

형태꼬리 호출?이유
(if done? answer (loop next))선택한 분기 결과를 그대로 반환
(begin (display x) (loop next))호출이 마지막 폼
(+ x (loop next))아니요재귀 결과 뒤에 덧셈이 남음
(map loop items)콜백은 아니요map이 콜백 결과를 더 처리
꼬리 위치의 (apply loop args)apply가 호출자의 꼬리 위치를 보존

흔한 오해

비꼬리 재귀는 선언된 자원 한도에 도달할 수 있습니다.

현재 경계

  • 깨끗한 자원 오류는 네이티브와 WASM 임계값이 같다는 증거가 아닙니다.

다음으로

재귀 가이드에서 기저 사례와 누산기 변환을 익히고, 꼬리 안전성이 무제한을 뜻하지 않는 이유는 결정성과 자원에서 확인하세요.

재귀 가이드 · 결정성과 자원