Newsgroup: it.comp.java
Titolo: tail recursion

Scusate la domanda... java e' un linguaggio che supporta la tail recursion?
Se costruisco un metodo tail recursive e lo invoco in modo "abbondante", lo stack mi si devasta o tutto funziona bene?
Grazie
CarMas

> lo stack mi si devasta o tutto funziona bene?
ma solitamente imposto un contatore
poi effetuo chiamate da loop for
for (i=0; i<7; i++) { chiama() };
non saprei
Grazie
CarMas
abbondanti Auguri 

 cosa devi fare ?
ottimizzazione di alcuni implementazioni di compilatori che riduce
drasticamente l'uso dello stack in presenza di funzioni ricorsive che
supportano caratteristiche particolari (semplificando enormemente... la
chiamata ricorsiva è l'ultimo statement valutato).
Per quanto ne so, nessun compilatore java supporta la tail recursion, ma
penso che sia pressochè banale controllare, basta scrivere una qualunque
funzione ricorsiva (il classico fattoriale, ad esempio) sia tentando di
sfruttare la tail recursion sia in versione naïve, e confrontare i tempi.
-- 
Under construction

 Under construction
mah,
allora se costruisco una classe e
racchiudo il tutto tra un
try {
..........
 loop + chiamate ricorsive
o
.........
}
catch() {}
oppure come dici tu un oggetto "a tempo"

 mah,
penso non ci siamo capiti...
guarda questo codice:
--8<------8<------8<------8<------8<------8<------8<------8<------8<----
public class Fact {
    public static void main(String[] args) {
        Fact f = new Fact();
        Integer n = 39;
        Long start, step, stop, media1 = new Long(0), media2 = new Long(0);
        for (Integer i = 0; i<100; i++) {
            start = System.nanoTime();
            f.fact1(n);
            step = System.nanoTime();
            f.fact2(n);
            stop = System.nanoTime();
            media1 = (media1*i + (step-start)) / (i+1);
            media2 = (media2*i + (stop-step)) / (i+1);
        }
        System.out.println("fact1("+ n +") took "+ media1 + " ns.");
        System.out.println("fact2("+ n +") took "+ media2 + " ns.");
        System.out.println();
    }
    Long fact1(Integer i) {
        if (i <= 1) return new Long(1);
        return i * fact1(i-1);
    }
    Long fact2(Integer i) {
        return fact2(i, new Long(1));
    }
    Long fact2(Integer i, Long f) {
        if (i<=1) return f;
        return fact2(i-1, f*i);
    }
}
--8<------8<------8<------8<------8<------8<------8<------8<------8<----
fact1 implementa la versione "naïve" del calcolo del fattoriale, praticamente
preso alla lettera dalla definizione matematica.
fact2 invece usa un parametro aggiuntivo, che viene usato come accumulatore
dei risultati parziali. Questo consente di avere come ultimo statement proprio la
chiamata ricorsiva (in fact1, dopo la chiamata ricorsiva, è necessario
moltiplicare il risultato parziale per i, e solo dopo la funzione termina)
-- 
Under construction

 penso non ci siamo capiti...
infatti, ma divagavo dal post originale...
non mio

sara' contento CarMas,
comunque buon Java tutti.
Ciao 

 penso non ci siamo capiti...
in definitiva sta TRO è fatta o no? :)
p.s. è cambiato qualcosa mentre io dormivo oppure usare Integer invece
che int per le computazioni è un buon modo per avere performance
teribbili? Io ero rimasti all'autoboxing quando necessario.
-- 
cc = callcc {|cc| cc.call cc}; cc.call cc

 writes:
Z> tentando di sfruttare la tail recursion sia in versione naïve, e
Z> confrontare i tempi.
Meglio controllare il bytecode generato con javap :)
-- 
 /\           ___                                    Ubuntu: ancient
/___/\_|_|\_|__|___Gian Uberto Lauri_____               African word
  //--\| | \|  |   Integralista GNUslamico            meaning "I can
\/                   e coltivatore diretto               not install
                               di software                   Debian"
a Cesare avrei detto di scrivermi | I would have told Caesar to write
a 
fn...@rat.vg
                    | me at 
fn...@rat.vg