Basitçe söylemek gerekirse, kuyruk özyinelemesi, derleyicinin özyinelemeli çağrıyı "goto" komutuyla değiştirebileceği bir özyinelemedir, bu nedenle derlenen sürümün yığın derinliğini arttırması gerekmez.
Bazen kuyruk özyinelemeli bir işlev tasarlamak, ek parametreler içeren bir yardımcı işlev oluşturmanız gerekir.
Örneğin, bu değil bir kuyruk özyinelemeli fonksiyon:
int factorial(int x) {
if (x > 0) {
return x * factorial(x - 1);
}
return 1;
}
Ancak bu kuyruk özyinelemeli bir işlevdir:
int factorial(int x) {
return tailfactorial(x, 1);
}
int tailfactorial(int x, int multiplier) {
if (x > 0) {
return tailfactorial(x - 1, x * multiplier);
}
return multiplier;
}
çünkü derleyici özyinelemeli işlevi özyinelemeli olmayan bir işlevle yeniden yazabilirdi (şuna benzer):
int tailfactorial(int x, int multiplier) {
start:
if (x > 0) {
multiplier = x * multiplier;
x--;
goto start;
}
return multiplier;
}
Derleyici kuralı çok basittir: " return thisfunction(newparameters);
" bulduğunuzda " " ile değiştirin parameters = newparameters; goto start;
. Ancak bu, özyinelemeli çağrının döndürdüğü değer doğrudan döndürüldüğünde yapılabilir.
Eğer bir fonksiyondaki bütün özyinelemeli çağrılar böyle değiştirilebilirse, o zaman bir özyinelemeli fonksiyondur.