Đợt đệ quy đuôi thường được thực hiện bằng cách sử dụng Tail calls. Điều này về cơ bản là một sự chuyển đổi của một cuộc gọi đệ quy thành một vòng lặp đơn giản.
C# Ví dụ:
uint FactorialAccum(uint n, uint accum) {
if(n < 2) return accum;
return FactorialAccum(n - 1, n * accum);
};
uint Factorial(uint n) {
return FactorialAccum(n, 1);
};
để
uint FactorialAccum(uint n, uint accum) {
start:
if(n < 2) return accum;
accum *= n;
n -= 1;
goto start;
};
uint Factorial(uint n) {
return FactorialAccum(n, 1);
};
hoặc thậm chí tốt hơn:
uint Factorial(uint n) {
uint accum = 1;
start:
if(n < 2) return accum;
accum *= n;
n -= 1;
goto start;
};
C không # thực đuôi đệ quy, điều này là do giá trị trả về được sửa đổi , hầu hết các trình biên dịch sẽ không phá vỡ điều này wn vào một vòng lặp:
int Power(int number, uint power) {
if(power == 0) return 1;
if(power == 1) return number;
return number * Power(number, --power);
}
để
int Power(int number, uint power) {
int result = number;
start:
if(power == 0) return 1;
if(power == 1) return number;
result *= number;
power--;
goto start;
}
chức năng đầu tiên của bạn không phải là đệ quy đuôi , do đó, điều này sẽ không được chuyển thành lặp lại trong Erlang. – Jules
Về cơ bản bạn là đúng, nhưng một trình biên dịch tốt sẽ có thể thấy cấu trúc. Tôi sẽ sửa đổi ví dụ của tôi sau. – Dykam
+ Lưu ý rằng hai hành động cuối cùng trước khi nhảy trở lại được bắt nguồn trực tiếp từ cuộc gọi đuôi. – Dykam