tailcall — 현재 프로시저를 다른 명령으로 교체하기
tailcall — 현재 프로시저를 다른 명령으로 교체하기
꼬리 재귀(tail recursion)를 쓰면 스택을 깊게 쌓지 않고 반복을 구현할 수 있어요. tailcall은 지금 실행 중인 프로시저(또는 람다 적용, 메서드)를 다른 명령으로 교체하는 명령이에요. 호출 스택을 키우지 않는다는 점이 핵심이에요.
본문
tailcall command ?arg ...?
tailcall은 현재 실행 중인 프로시저, 람다 적용, 메서드를 다른 명령으로 교체해요. arg ...가 제공되면 그 인자들과 함께 실행될 이 명령은, 호출자의 네임스페이스가 아니라 현재 네임스페이스 컨텍스트에서 찾아져요. 그 해석 방식의 차이만 빼면 다음 명령과 동일해요.
return [uplevel 1 [list command ?arg ...?]]
이 명령은 uplevel로 프로시저 안으로 올라간 상태에서 호출하거나, 프로시저나 람다 안의 catch 내부에서 호출할 수는 없어요.
예제
숫자의 팩토리얼을 계산해 볼게요.
proc factorial {n {accum 1}} {
if {$n < 2} {
return $accum
}
tailcall factorial [expr {$n - 1}] [expr {$accum * $n}]
}
리스트의 요소를 번갈아 들여쓰기하면서 출력하는 예시예요.
proc printList {theList} {
if {[llength $theList]} {
puts "> [lindex $theList 0]"
tailcall printList2 [lrange $theList 1 end]
}
}
proc printList2 {theList} {
if {[llength $theList]} {
puts "< [lindex $theList 0]"
tailcall printList [lrange $theList 1 end]
}
}