2015-06-09 19 views
6

supose si ha una funzione ricorsiva come:È una coda? (Javascript)

Blah.prototype.add = function(n) { 
    this.total += n; 
    this.children.forEach(function(child) { 
     child.add(n); 
    }); 
}; 

È la child.add() una chiamata coda? Se no, può essere scritto così è?

+0

Direi così. Anche se si trova all'interno di un ciclo, è ancora l'ultima azione eseguita. – Brennan

+0

Non ero sicuro ... stavo pensando a un ciclo tradizionale 'for (i = 0; i pixelmike

+0

Presumibilmente un 'tail call 'in JS renderebbe l'uso di' return someFn() 'permettendo anche alla funzione initator di essere garbage collection. –

risposta

1

Sì, si tratta di una chiamata coda:

function(child) { 
    child.add(n); 
//^tail 
} 

Eppure qui non c'è una coda ricorsiva, perché non è una chiamata ricorsiva diretta.

Anche this.children.forEach(…) è una chiamata di coda all'interno del metodo add.

Tuttavia, l'invocazione del callback all'interno del metodo nativo forEach non è probabilmente ottimizzata in coda (e tutto tranne l'ultimo non può essere comunque). È possibile forzarlo riscrivendo la funzione di

Blah.prototype.add = function(n) { 
    "use strict"; 
    this.total += n; 
    let l = this.children.length; 
    if (!l--) 
     return; 
    for (let i=0; i<l; i++) 
     this.children[i].add(n); 
    this.children[i].add(n); // tail-recursion 
}; 

noti che nessuna di queste chiamate di coda sarà ottimizzato Se non anche return i loro risultati.

+0

Sei sicuro che 'add' è tail-ricorsivo? Anche se è stato utilizzato un costrutto di ciclo semplice, l'ultima operazione eseguita sarebbe il controllo condizionale del ciclo, quindi non sarebbe ricorsivo in coda, no?Ho pensato che la chiamata ricorsiva doveva essere l'ultima espressione eseguita affinché un algoritmo fosse ricorsivo in coda. – plalx

+0

@plalx: non ho detto che "add" era ricorsivo in coda. Se è stato reciprocamente ricorsivo con 'forEach' e il suo callback - non si chiama da solo. Ho solo detto che 'add' contiene una coda. – Bergi

+0

Grazie, sì avrei dovuto essere chiaro che stavo chiedendo se child.add fosse una coda per la funzione add, non per il callback forEach. – pixelmike

1

Are any Javascript engines tail call optimized?

JavaScript come al momento non è ottimizzerà per quella

Un'altra opzione sarebbe un trampolino https://taylodl.wordpress.com/2013/06/07/functional-javascript-tail-call-optimization-and-trampolines/

+0

Sì, non pensavo che l'ottimizzazione fosse già in atto, ma sto cercando di prepararmi per quando è. Grazie per i link. – pixelmike

+0

Quella domanda che hai collegato è superata. ES6 sta avendo un'ottica ottimizzazione della coda. – Bergi

+0

Correggimi se ho torto ma ES6 non è ancora uscito? – exussum