TL; DR: Các ngôn ngữ chức năng có xử lý đệ quy tốt hơn các ngôn ngữ không chức năng không?
Tôi hiện đang đọc Code Complete 2. Tại một số điểm trong cuốn sách, tác giả cảnh báo chúng tôi về đệ quy. Ông nói rằng nên tránh khi có thể và các chức năng sử dụng đệ quy thường kém hiệu quả hơn so với giải pháp sử dụng các vòng lặp. Ví dụ, tác giả đã viết một hàm Java bằng cách sử dụng đệ quy để tính giai thừa của một số như vậy (nó có thể không hoàn toàn giống nhau vì tôi không có cuốn sách này vào lúc này):
public int factorial(int x) {
if (x <= 0)
return 1;
else
return x * factorial(x - 1);
}
Đây là một giải pháp tồi. Tuy nhiên, trong các ngôn ngữ chức năng, sử dụng đệ quy thường là cách làm được ưa thích. Ví dụ, đây là hàm giai thừa trong Haskell bằng cách sử dụng đệ quy:
factorial :: Integer -> Integer
factorial 0 = 1
factorial n = n * factorial (n - 1)
Và được chấp nhận rộng rãi như một giải pháp tốt. Như tôi đã thấy, Haskell sử dụng đệ quy rất thường xuyên và tôi không thấy bất cứ nơi nào nó được tán thành.
Vì vậy, câu hỏi của tôi về cơ bản là:
- Các ngôn ngữ chức năng xử lý đệ quy tốt hơn các ngôn ngữ không chức năng?
EDIT: Tôi biết rằng các ví dụ tôi đã sử dụng không phải là tốt nhất để minh họa câu hỏi của tôi. Tôi chỉ muốn chỉ ra rằng Haskell (và các ngôn ngữ chức năng nói chung) sử dụng đệ quy thường xuyên hơn nhiều so với các ngôn ngữ phi chức năng.
factorial n = product [1..n]
ngắn gọn hơn, hiệu quả hơn và không tràn vào ngăn xếp cho lớn n
(và nếu bạn cần ghi nhớ, các tùy chọn hoàn toàn khác nhau được yêu cầu). product
được định nghĩa theo một số fold
, được định nghĩa đệ quy, nhưng hết sức cẩn thận. Đệ quy là một giải pháp có thể chấp nhận được hầu hết thời gian, nhưng vẫn dễ dàng thực hiện sai / không tối ưu.