tailcall — 현재 프로시저를 다른 명령으로 교체하기

tailcall — 현재 프로시저를 다른 명령으로 교체하기

꼬리 재귀(tail recursion)를 쓰면 스택을 깊게 쌓지 않고 반복을 구현할 수 있어요. tailcall은 지금 실행 중인 프로시저(또는 람다 적용, 메서드)를 다른 명령으로 교체하는 명령이에요. 호출 스택을 키우지 않는다는 점이 핵심이에요.

출처: Tcl 공식 문서 - 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]
    }
}

더 알아보기

  • apply — 람다 적용
  • proc — 프로시저 정의
  • uplevel — 더 높은 스택 레벨에서 명령 실행