Recursion মানে একটি function একই সমস্যার একটি ছোট version দিয়ে নিজেকে call করে সমস্যা সমাধান করে, যতক্ষণ না এটা সরাসরি উত্তর দেওয়ার মতো যথেষ্ট সহজ একটি version-এ পৌঁছায়।
function factorial(n) {
if (n <= 1) {
return 1 // base case — recursion থামায়
}
return n * factorial(n - 1) // recursive case
}
factorial(5) // 5 * 4 * 3 * 2 * 1 = 120এটা থামায় এমন একটি শর্ত ছাড়া, একটি recursive function চিরকাল নিজেকে call করে — বা আরো সঠিকভাবে, call stack-এর জায়গা শেষ না হওয়া পর্যন্ত।
function countDown(n) {
// base case নেই — এটা নিজে থেকে কখনো থামে না
console.log(n)
countDown(n - 1)
}
// countDown(5) শেষ পর্যন্ত throw করে:
// "Maximum call stack size exceeded"সবচেয়ে common recursion bug
প্রতিটি recursive function-এর সত্যিকারভাবে পৌঁছানো যায় এমন একটি base case দরকার — কখনো trigger না হওয়া একটি base case (একটি ভুল comparison, কখনো এর দিকে converge না করা একটি argument) কোনো base case না থাকার মতোই একই রকম ব্যর্থ হয়।
প্রতিটি recursive call call stack-এ (আগের Event Loop lesson থেকে) একটি নতুন frame যোগ করে — এটা যে গভীর call করেছে তার প্রতিটি return না হওয়া পর্যন্ত function আসলে শেষ হয় না।
factorial(3)
// factorial(3) factorial(2)-কে call করে
// factorial(2) factorial(1)-কে call করে
// factorial(1) 1 return করে
// factorial(2) 2 * 1 = 2 return করে
// factorial(3) 3 * 2 = 6 return করে| Recursion | একটি Loop |
|---|---|
| স্বাভাবিকভাবে recursive একটি সমস্যার জন্য (একটি tree traverse করা, nested data) প্রায়ই বেশি স্বাভাবিক দেখায় | একটি সহজ repeated কাজের জন্য সাধারণত দ্রুত আর কম memory ব্যবহার করে |
| প্রতিটি call একটি call stack frame যোগ করে — গভীর recursion একটি stack size limit-এ পৌঁছাতে পারে | যত iteration-ই হোক না কেন কোনো stack depth উদ্বেগ নেই |
Interactively practice করুন
এই সাইটের Recursion tool (Tools-এর নিচে) একটি কোডের জন্য call tree ধাপে ধাপে unwind হওয়া visualize করে — হাতে trace করার চেয়ে "প্রতিটি call পরেরটার জন্য অপেক্ষা করে" আসলে কেমন দেখতে তা দেখার একটি স্পষ্ট উপায়।