Functional Programming (FP)

"The Art of Clean & Predictable Code"

জাভাস্ক্রিপ্ট একটি Multi-paradigm ল্যাঙ্গুয়েজ। অর্থাৎ এখানে OOP (Object Oriented) এবং FP (Functional Programming) দুটোই করা যায়।

OOP ফোকাস করে: "জিনিসটা দেখতে কেমন?" (Objects, Classes)
FP ফোকাস করে: "কাজটা কীভাবে হবে?" (Data Flow, Functions)

React, Redux, বা বড় বড় সিস্টেমে বাগ-ফ্রি কোড লিখতে হলে FP-র কোনো বিকল্প নেই। চলো, ফাংশনাল প্রোগ্রামিংয়ের জগতে ডুব দেই।

⭐ ১. First-Class Functions: ক্ষমতার উৎস

ফাংশনাল প্রোগ্রামিং সম্ভব কারণ জাভাস্ক্রিপ্টে ফাংশন হলো "First-Class Citizens"। এর মানে ফাংশনকে তুমি ভেরিয়েবলের মতো ব্যবহার করতে পারো।

  • ভেরিয়েবলে রাখা যায়
  • আর্গুমেন্ট হিসেবে পাস করা যায়
  • ফাংশন থেকে রিটার্ন করা যায়
const sayHello = () => "Hello World"; // ভেরিয়েবলে রাখলাম
const run = (fn) => console.log(fn()); // আর্গুমেন্ট হিসেবে পাস করলাম
run(sayHello);

⭐ ২. Pure Functions: ভেজাল মুক্ত ফাংশন 🧪

সিনিয়র ডেভেলপার হওয়ার প্রথম শর্ত: তোমার কোডের ৮০% ফাংশন হতে হবে Pure

Pure Function এর বৈশিষ্ট্য:

  • Same Input = Same Output: ইনপুট এক হলে রেজাল্ট সবসময় এক হবে
  • No Side Effects: বাইরের কোনো ভেরিয়েবল বা স্টেট পরিবর্তন করবে না

❌ Impure (ভেজাল)

let tax = 10;
function calculatePrice(price) {
    return price + tax; // বাইরের 'tax' এর ওপর নির্ভরশীল
}

সমস্যা: কাল যদি কেউ tax এর মান বদলে দেয়, তবে এই ফাংশনের আউটপুট বদলে যাবে। এটা আনপ্রেডিক্টেবল।

✅ Pure (খাঁটি)

function calculatePrice(price, tax) {
    return price + tax; // যা দরকার সব ইনপুটেই আছে
}

সুবিধা: টেস্টিং করা সহজ, বাগ হওয়ার সুযোগ নেই।

⭐ ৩. Immutability: ইতিহাস পরিবর্তন নিষিদ্ধ 🛡️

React ডেভেলপারদের জন্য এটা ফরজ। Immutability মানে হলো: ডাটা কখনো মডিফাই (Change) করা যাবে না, নতুন করে তৈরি (Replace) করতে হবে।

❌ Mutating (Dangerous)

const user = { name: "Rahim", age: 25 };
user.age = 26; // অরিজিনাল অবজেক্ট নষ্ট হলো

✅ Immutable (Safe)

const user = { name: "Rahim", age: 25 };
// স্প্রেড (...) অপারেটর দিয়ে কপি করে নতুন বানালাম
const updatedUser = { ...user, age: 26 };

কেন দরকার? React এবং Redux আগের এবং পরের স্টেটের পার্থক্য (Diffing) চেক করে। মিউটেট করলে তারা বুঝতেই পারে না কিছু চেঞ্জ হয়েছে কিনা।

⭐ ৪. Higher-Order Functions (HOF): বসের বস

যে ফাংশন অন্য ফাংশনকে হুকুম দেয় বা বানায়, তাকে HOF বলে। map, filter, reduce হলো জাভাস্ক্রিপ্টের বিল্ট-ইন HOF।

// কাস্টম HOF
function repeat(n, action) {
    for (let i = 0; i < n; i++) {
        action(i); // action ফাংশনটি কল করা হচ্ছে
    }
}

repeat(3, console.log); // 0, 1, 2

⭐ ৫. Currying: ধাপে ধাপে কাজ 🍛

এটি ইন্টারভিউতে খুব প্রিয় প্রশ্ন। কারিং মানে হলো একটি ফাংশন যা অনেকগুলো আর্গুমেন্ট নেয়, তাকে ভেঙে এমন করা যেন সে একবারে একটি করে আর্গুমেন্ট নেয়।

f(a, b, c) কে f(a)(b)(c) তে রূপান্তর করা।

Normal Function:

const add = (a, b) => a + b;
add(5, 10);

Curried Function:

const add = (a) => (b) => a + b;

const addFive = add(5); // ৫ মনে রাখল (Closure)
console.log(addFive(10)); // ১৫
console.log(addFive(20)); // ২৫

Real Life Use: ধরো তোমার একটি ডিসকাউন্ট ফাংশন আছে। তুমি 10% ডিসকাউন্ট ফিক্স করে একটা ফাংশন বানিয়ে রাখতে চাও।

⭐ ৬. Composition & Pipe: পাইপলাইন আর্কিটেকচার 🏭

ফাংশনাল প্রোগ্রামিংয়ের সৌন্দর্য হলো ছোট ছোট ফাংশন জোড়া লাগিয়ে বড় কাজ করা। ধরা যাক, একটি সংখ্যার সাথে ৫ যোগ করতে হবে, তারপর সেটাকে দ্বিগুণ করতে হবে।

The Ugly Way:

const result = double(add5(10)); // নেস্টেড, পড়তে কষ্ট হয়

The Clean Way (Composition/Pipe):

const add5 = x => x + 5;
const double = x => x * 2;

// পাইপ ফাংশন: বাম থেকে ডানে ডেটা ফ্লো করে
const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);

const calculate = pipe(add5, double);
console.log(calculate(10)); // (10 + 5) * 2 = 30

Redux এর compose বা লজিক পাইপলাইন এভাবেই কাজ করে।

⭐ ৭. Recursion: লুপ ছাড়া লুপিং 🔄

ফাংশনাল প্রোগ্রামিংয়ে লুপের চেয়ে Recursion (নিজেকে কল করা) বেশি পছন্দ করা হয়, বিশেষ করে ট্রি স্ট্রাকচার বা নেস্টেড ডেটার জন্য।

// Factorial (5! = 5*4*3*2*1)
function factorial(n) {
    if (n === 1) return 1; // বেস কন্ডিশন (থামার জন্য)
    return n * factorial(n - 1);
}

🧠 ৮. Senior Level Interview Questions

Q1: Pure Function এবং Impure Function এর মূল পার্থক্য কী?

উত্তর: Pure Function সবসময় একই ইনপুটের জন্য একই আউটপুট দেয় এবং সাইড ইফেক্ট মুক্ত। Impure Function বাইরের স্টেটের ওপর নির্ভর করে বা পরিবর্তন করে (যেমন API Call, DOM manipulation)।

Q2: Immutability কেন React এ গুরুত্বপূর্ণ?

উত্তর: React অবজেক্টের রেফারেন্স চেক করে রেন্ডার ডিসিশন নেয়। মিউটেট করলে রেফারেন্স সেম থাকে, তাই React বোঝে না যে ডেটা বদলেছে, ফলে UI আপডেট হয় না।

Q3: Currying এর একটি প্র্যাক্টিক্যাল উদাহরণ দিন।

উত্তর: ইভেন্ট হ্যান্ডলারে কনফিগারেশন পাস করতে। যেমন: handleChange('name')(event)। এখানে প্রথম ফাংশন ফিল্ডের নাম নেয়, পরেরটা ইভেন্ট অবজেক্ট।

Q4: Function Composition কী?

উত্তর: ছোট ছোট ফাংশনকে জোড়া লাগিয়ে একটি পাইপলাইন তৈরি করা, যেখানে একটার আউটপুট পরেরটার ইনপুট হিসেবে কাজ করে।

⭐ ৯. Real World FP Example: Shopping Cart 🛒

চলো সব কনসেপ্ট একসাথে দেখি:

const cart = [
    { name: "Apple", price: 100, active: true },
    { name: "Orange", price: 50, active: false },
    { name: "Banana", price: 80, active: true }
];

// 1. Pure Helper Functions
const isActive = item => item.active;
const getPrice = item => item.price;
const sum = (acc, price) => acc + price;

// 2. Functional Pipeline (Chain)
const totalActivePrice = cart
    .filter(isActive) // শুধু একটিভ গুলো নাও
    .map(getPrice)    // শুধু দামগুলো বের করো
    .reduce(sum, 0);  // যোগ করো

console.log(totalActivePrice); // 180

দেখো কোডটা কত ক্লিন! এটাই ফাংশনাল প্রোগ্রামিংয়ের শক্তি।

🚀 অধ্যায় ১৪ সারাংশ (Checklist)

আমরা শিখলাম:

  • Pure Function: ইনপুট -> আউটপুট (নো সাইড ইফেক্ট)
  • Immutability: কপি করে চেঞ্জ করা, ডাইরেক্ট চেঞ্জ না করা
  • Currying: f(a)(b) স্টাইল, রিইউজেবল লজিকের জন্য
  • Composition: ফাংশন জোড়া লাগানোর পাইপলাইন
  • Declarative: "কী চাই" সেটা বলা (যেমন filter), "কিভাবে চাই" সেটা না (যেমন for loop)

Next Step: কোড লেখা তো হলো, কিন্তু কোডে যদি ভুল থাকে? বাগ হ্যান্ডেল করার আর্ট শিখতে হবে। পরের অধ্যায়: "Error Handling & Debugging Like a Pro"।

🔒 কপিরাইট সুরক্ষিত কন্টেন্ট 🔒

কপি, স্ক্রিনশট, প্রিন্ট করা সম্পূর্ণ নিষিদ্ধ।