Clojure, kuyruk çağrısı optimizasyonunu kendi başına yapmaz: kuyruk özyinelemeli bir işleve sahip olduğunuzda ve optimize edilmesini istediğinizde, özel formu kullanmanız gerekir recur
. Benzer şekilde, karşılıklı olarak iki özyinelemeli işleviniz varsa, bunları yalnızca kullanarak optimize edebilirsiniz trampoline
.
Scala derleyicisi özyinelemeli bir işlev için TCO'yu gerçekleştirebilir, ancak iki özyinelemeli işlev için yapamaz.
Ne zaman bu sınırlamaları okuduğumda, her zaman JVM modeline özgü bazı sınırlamalara bağlandılar. Derleyiciler hakkında hiçbir şey bilmiyorum, ama bu beni biraz şaşırtıyor. Örnek alalım Programming Scala
. İşte işlev
def approximate(guess: Double): Double =
if (isGoodEnough(guess)) guess
else approximate(improve(guess))
çevrildi
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
Yani, bytecode düzeyinde, sadece bir ihtiyacı var goto
. Bu durumda, aslında, zor iş derleyici tarafından yapılır.
Temel sanal makinenin hangi tesisi derleyicinin TCO'yu daha kolay ele almasına izin verir?
Bir yandan not olarak, gerçek makinelerin JVM'den daha akıllı olmasını beklemem. Yine de, Haskell gibi yerel kodları derleyen birçok dilde, kuyruk çağrılarını optimize etme konusunda bir sorun yok gibi görünüyor (peki, Haskell'in bazen tembellik nedeniyle olabilir, ama bu başka bir konudur).