Clojure는 자체적으로 테일 콜 최적화를 수행하지 않습니다. 테일 재귀 함수가 있고이를 최적화하려면 특수 양식을 사용해야합니다 recur
. 마찬가지로 두 개의 상호 재귀 함수가있는 경우을 사용해서 만 최적화 할 수 있습니다 trampoline
.
Scala 컴파일러는 재귀 함수에 대해서는 TCO를 수행 할 수 있지만 두 개의 상호 재귀 함수에는 사용할 수 없습니다.
이러한 제한 사항에 대해 읽을 때마다 항상 JVM 모델에 내재 된 일부 제한 사항이 발생했습니다. 나는 컴파일러에 대해 거의 아무것도 모른다. 그러나 이것은 나를 조금 당혹스럽게한다. 에서 예제를 보도록하겠습니다 Programming Scala
. 여기 기능
def approximate(guess: Double): Double =
if (isGoodEnough(guess)) guess
else approximate(improve(guess))
로 번역
0: aload_0
1: astore_3
2: aload_0
3: dload_1
4: invokevirtual #24; //Method isGoodEnough:(D)Z
7: ifeq
10: dload_1
11: dreturn
12: aload_0
13: dload_1
14: invokevirtual #27; //Method improve:(D)D
17: dstore_1
18: goto 2
따라서 바이트 코드 수준에서는 goto
. 이 경우 실제로는 힘든 일이 컴파일러에 의해 수행됩니다.
컴파일러가 TCO를보다 쉽게 처리 할 수있는 기본 가상 머신의 기능
참고로, 실제 머신이 JVM보다 훨씬 더 똑똑하지는 않을 것입니다. 그럼에도 불구하고 Haskell과 같은 네이티브 코드로 컴파일되는 많은 언어는 꼬리 호출을 최적화하는 데 문제가없는 것으로 보입니다 (Hassell은 때로는 게으름으로 인해 발생할 수 있지만 또 다른 문제입니다).