No, Ruby non esegue il TCO. Tuttavia, anche lo non esegue TCO.
La specifica del linguaggio Ruby non dice nulla sul TCO. Non dice che devi farlo, ma non ti dice neanche che lo non può farlo. Non puoi semplicemente contare su.
Questo è diverso schema, in cui la lingua specifica richiede che tutti Implementazioni deve eseguire TCO. Ma è anche diverso da Python, dove Guido van Rossum ha reso molto chiaro in diverse occasioni (l'ultima volta solo un paio di giorni fa) che le implementazioni Python non dovevano eseguire il TCO.
Yukihiro Matsumoto è in sintonia con il TCO, non vuole forzare lo tutte le implementazioni per supportarlo. Sfortunatamente, questo significa che non puoi fare affidamento sul TCO, o se lo fai, il tuo codice non sarà più portabile ad altre Implementazioni di Ruby.
Quindi, alcune implementazioni di Ruby eseguono il TCO, ma la maggior parte no. YARV, ad esempio, supporta il TCO, anche se (per il momento) devi annullare esplicitamente una riga nel codice sorgente e ricompilare la VM, per attivare il TCO - nelle versioni future sarà attivata per impostazione predefinita, dopo che l'implementazione si sarà dimostrata stabile. Parrot Virtual Machine supporta nativamente il TCO, quindi Cardinal potrebbe tranquillamente supportarlo. Il CLR ha qualche supporto per il TCO, il che significa che IronRuby e Ruby.NET potrebbero probabilmente farlo. Rubinio potrebbe probabilmente farlo anche lui.
Ma JRuby e XRuby non supportano il TCO e probabilmente non lo faranno, a meno che la JVM stessa non supporti il TCO. Il problema è questo: se si desidera un'implementazione rapida e un'integrazione rapida e perfetta con Java, è necessario utilizzare lo stack compatibile con Java e utilizzare lo stack JVM il più possibile. Puoi facilmente implementare il TCO con trampolini o lo stile di passaggio continuo, ma non utilizzerai più lo stack JVM, il che significa che ogni volta che desideri chiamare in Java o chiamare da Java a Ruby, devi eseguire una sorta di conversione, che è lento. Quindi, XRuby e JRuby hanno scelto di andare con velocità e integrazione di Java su TCO e continuazioni (che fondamentalmente hanno lo stesso problema).
Questo vale per tutte le implementazioni di Ruby che desiderano integrarsi strettamente con alcune piattaforme host che non supportano il TCO in modo nativo. Ad esempio, suppongo che MacRuby abbia lo stesso problema.
Potrei sbagliarmi (per favore mi illumini se è così), ma dubito che il TCO abbia senso in veri linguaggi OO, dal momento che la coda deve essere in grado di riutilizzare il frame dello stack del chiamante. Poiché con l'associazione tardiva, non è noto in fase di compilazione quale metodo verrà invocato da un messaggio di invio, sembra difficile garantirlo (magari con un JIT di tipo feedback o forzando tutti gli implementatori di un messaggio a utilizzare i frame dello stack della stessa dimensione o limitando il TCO alle auto-mandate dello stesso messaggio ...). –
Questa è una grande risposta. Queste informazioni non sono facilmente reperibili tramite Google. Interessante che yarv lo supporti. –
Damien, si scopre che il TCO è effettivamente * richiesto * per le lingue OO reali: vedere http://projectfortress.sun.com/Projects/Community/blog/ObjectOrientedTailRecursion. Non preoccuparti troppo del materiale dello stack frame: è perfettamente possibile progettare sensibilmente i telai dello stack in modo che funzionino bene con il TCO. –