Ricerca…
Sintassi
- solo restituire call () in modo implicito, ad esempio nella funzione freccia o in modo esplicito, può essere una coda chiamata stat
- function foo () {return bar (); } // il call to bar è una coda
- function foo () {bar (); } // bar non è una coda. La funzione restituisce un valore non definito quando non viene restituito alcun risultato
- const foo = () => bar (); // bar () è una coda
- const foo = () => (poo (), bar ()); // poo non è una coda, il bar è una coda
- const foo = () => poo () && bar (); // poo non è una coda, il bar è una coda
- const foo = () => bar () + 1; // bar non è una coda, poiché richiede il contesto per restituire + 1
Osservazioni
Il TCO è anche noto come PTC (Proper Tail Call) come indicato nelle specifiche ES2015.
Cos'è l'ottimizzazione delle chiamate tail (TCO)
TCO è disponibile solo in modalità rigorosa
Come sempre, controlla le implementazioni di browser e Javascript per il supporto di tutte le funzionalità del linguaggio e, come con qualsiasi funzione o sintassi javascript, potrebbe cambiare in futuro.
Fornisce un modo per ottimizzare le chiamate di funzione ricorsive e profondamente annidate, eliminando la necessità di spingere lo stato della funzione nello stack di frame globale ed evitando di dover scendere attraverso ogni funzione di chiamata ritornando direttamente alla funzione di chiamata iniziale.
function a(){
return b(); // 2
}
function b(){
return 1; // 3
}
a(); // 1
Senza il TCO, la chiamata a a()
crea una nuova cornice per quella funzione. Quando quella funzione chiama b()
il frame di a()
viene inserito nello stack dei frame e viene creato un nuovo frame per la funzione b()
Quando b()
ritorno ad a()
a()
's telaio viene estratto dallo stack telaio. Ritorna immediatamente al frame globale e quindi non usa nessuno degli stati salvati nello stack.
Il TCO riconosce che la chiamata da a()
a b()
è alla coda della funzione a()
e quindi non è necessario spingere lo a()
sullo stack di frame. Quando b(0)
restituisce anziché tornare a a()
, ritorna direttamente al frame globale. Ulteriore ottimizzazione eliminando i passaggi intermedi.
Il TCO consente alle funzioni ricorsive di avere una ricorsione indefinita in quanto lo stack di frame non cresce con ogni chiamata ricorsiva. Senza la funzione ricorsiva del TCO aveva una profondità ricorsiva limitata.
Nota TCO è una funzionalità di implementazione del motore javascript, non può essere implementata tramite un transpiler se il browser non lo supporta. Non vi è alcuna sintassi aggiuntiva nelle specifiche richieste per implementare il TCO e quindi vi è la preoccupazione che il TCO possa interrompere il web. Il suo rilascio nel mondo è cauto e potrebbe richiedere l'impostazione di browser / specifiche del motore per il futuro percepibile.
Loop ricorsivi
Tail Call Optimization rende possibile implementare in sicurezza loop ricorsivi senza preoccuparsi di overflow dello stack delle chiamate o di sovraccarico di stack di frame in crescita.
function indexOf(array, predicate, i = 0) {
if (0 <= i && i < array.length) {
if (predicate(array[i])) { return i; }
return indexOf(array, predicate, i + 1); // the tail call
}
}
indexOf([1,2,3,4,5,6,7], x => x === 5); // returns index of 5 which is 4