TL; DR: ภาษาที่ใช้งานได้จัดการการเรียกซ้ำได้ดีกว่าภาษาที่ไม่ทำงานหรือไม่
ขณะนี้ฉันกำลังอ่าน Code Complete 2 ในบางช่วงของหนังสือผู้แต่งเตือนเราเกี่ยวกับการเรียกซ้ำ เขาบอกว่าควรหลีกเลี่ยงเมื่อเป็นไปได้และฟังก์ชั่นที่ใช้การเรียกซ้ำโดยทั่วไปมีประสิทธิภาพน้อยกว่าโซลูชันที่ใช้ลูป ตัวอย่างผู้เขียนเขียนฟังก์ชัน Java โดยใช้การเรียกซ้ำเพื่อคำนวณแฟกทอเรียลของตัวเลขเช่นนั้น (อาจไม่เหมือนกันทั้งหมดเนื่องจากฉันไม่มีหนังสือกับฉันในขณะนี้):
public int factorial(int x) {
if (x <= 0)
return 1;
else
return x * factorial(x - 1);
}
นี่เป็นวิธีแก้ปัญหาที่ไม่ดี อย่างไรก็ตามในภาษาที่ใช้งานได้การใช้การเรียกซ้ำเป็นวิธีที่นิยมใช้ในการทำสิ่งต่างๆ ตัวอย่างเช่นนี่คือฟังก์ชันแฟกทอเรียลใน Haskell โดยใช้การเรียกซ้ำ:
factorial :: Integer -> Integer
factorial 0 = 1
factorial n = n * factorial (n - 1)
และได้รับการยอมรับอย่างกว้างขวางว่าเป็นทางออกที่ดี อย่างที่ฉันได้เห็น Haskell ใช้การเรียกซ้ำบ่อยมากและฉันไม่เห็นว่ามันขมวดคิ้ว
ดังนั้นคำถามของฉันโดยทั่วไปคือ:
- ภาษาที่ใช้งานได้จัดการการเรียกซ้ำได้ดีกว่าภาษาที่ไม่ใช้การได้หรือไม่?
แก้ไข: ฉันรู้ว่าตัวอย่างที่ฉันใช้นั้นไม่ได้ดีที่สุดในการอธิบายคำถามของฉัน ฉันแค่ต้องการชี้ให้เห็นว่า Haskell (และภาษาที่ใช้งานได้ทั่วไป) ใช้การเรียกซ้ำบ่อยกว่าภาษาที่ไม่สามารถใช้งานได้
factorial n = product [1..n]
รวบรัดมากขึ้นมีประสิทธิภาพมากขึ้นและไม่ล้นสแต็กสำหรับขนาดใหญ่n
(และถ้าคุณต้องการบันทึกช่วยจำต้องใช้ตัวเลือกที่แตกต่างกันโดยสิ้นเชิง) product
ถูกกำหนดในแง่ของบางอย่างfold
ซึ่งถูกกำหนดแบบเรียกซ้ำ แต่ด้วยความระมัดระวัง การเรียกซ้ำเป็นวิธีแก้ปัญหาที่ยอมรับได้ส่วนใหญ่ แต่ก็ยังง่ายที่จะทำผิด / ไม่เหมาะสม