কন্ডিশনাল স্টেটমেন্টস (Conditional Statements in Clojure)
ক্লোজারে (Clojure) কন্ডিশনাল স্টেটমেন্ট ব্যবহার করে বিভিন্ন শর্ত অনুযায়ী সিদ্ধান্ত নেওয়া হয়। সাধারণত, ক্লোজারে শর্ত নির্ধারণের জন্য if, when, cond, এবং case স্টেটমেন্ট ব্যবহৃত হয়। এই স্টেটমেন্টগুলো কোডের মধ্যে শর্তের উপর ভিত্তি করে বিভিন্ন কাজ করতে সহায়ক। নিচে প্রতিটি কন্ডিশনাল স্টেটমেন্ট নিয়ে বিস্তারিত আলোচনা করা হলো।
১. if কন্ডিশন (if Condition)
if স্টেটমেন্টটি ক্লোজারে শর্ত পরীক্ষা করতে ব্যবহৃত হয়। এটি দুইটি আর্গুমেন্ট নেয়: একটি then এবং একটি else। শর্তটি সত্য হলে then অংশটি কার্যকর হয়; অন্যথায় else অংশটি কার্যকর হয়।
(if true
"সত্য"
"মিথ্যা")
; আউটপুট: "সত্য"উদাহরণ:
(defn even-or-odd [x]
(if (even? x)
"জোড় সংখ্যা"
"বিজোড় সংখ্যা"))
(even-or-odd 4) ; আউটপুট: "জোড় সংখ্যা"
(even-or-odd 5) ; আউটপুট: "বিজোড় সংখ্যা"এখানে, even-or-odd ফাংশনটি সংখ্যা x এর জোড় বা বিজোড় হওয়া চেক করে এবং ফলাফল প্রদান করে।
২. when কন্ডিশন (when Condition)
when স্টেটমেন্টটি if এর মতই কাজ করে, কিন্তু এটি কেবল শর্ত সত্য হলে কার্যকর হয় এবং একটি এক্সপ্রেশন ব্লক পরিচালনা করে। এটি একাধিক এক্সপ্রেশন একত্রে চালাতে সক্ষম।
(when true
(println "শর্তটি সত্য")
"ফলাফল")
; আউটপুট: "শর্তটি সত্য"
; আউটপুট: "ফলাফল"উদাহরণ:
(defn check-positive [x]
(when (> x 0)
(println "ধনাত্মক সংখ্যা")
x))
(check-positive 5) ; আউটপুট: "ধনাত্মক সংখ্যা" এবং 5এখানে, check-positive ফাংশনটি শুধুমাত্র সংখ্যা x ধনাত্মক হলে println এবং x ফিরিয়ে দেয়।
৩. cond কন্ডিশন (cond Condition)
cond স্টেটমেন্টটি একাধিক শর্ত পরীক্ষা করতে ব্যবহৃত হয়। এটি অনেকগুলি শর্ত এবং সংশ্লিষ্ট ফলাফল একত্রে পরীক্ষা করে। প্রথম সত্য শর্তটি পাওয়া মাত্র তা কার্যকর হয় এবং বাকিগুলি উপেক্ষা করা হয়।
(cond
(= 5 10) "সমান নয়"
(> 5 2) "বড়"
:else "অজানা")
; আউটপুট: "বড়"উদাহরণ:
(defn grade [marks]
(cond
(>= marks 80) "A"
(>= marks 70) "B"
(>= marks 60) "C"
:else "Fail"))
(grade 75) ; আউটপুট: "B"এখানে, grade ফাংশনটি শিক্ষার্থীর মার্কস অনুযায়ী গ্রেড নির্ধারণ করে।
৪. case কন্ডিশন (case Condition)
case স্টেটমেন্টটি নির্দিষ্ট মানের জন্য ব্যবহৃত হয় এবং এটি switch স্টেটমেন্টের মত কাজ করে। এটি একটি মান নেয় এবং তার সাথে মিলে যাওয়া মানের ক্ষেত্রে ফলাফল প্রদান করে।
(case 3
1 "এক"
2 "দুই"
3 "তিন"
"অজানা")
; আউটপুট: "তিন"উদাহরণ:
(defn day-of-week [day]
(case day
"Monday" "সোমবার"
"Tuesday" "মঙ্গলবার"
"Wednesday" "বুধবার"
"Unknown day"))
(day-of-week "Tuesday") ; আউটপুট: "মঙ্গলবার"এখানে, day-of-week ফাংশনটি দিন অনুযায়ী বাংলা নাম ফেরত দেয়। যদি কোনো মিল পাওয়া না যায়, তবে Unknown day ফেরত দেয়।
৫. and এবং or লজিক্যাল অপারেটরস (Logical Operators: and, or)
and এবং or অপারেটর দিয়ে একাধিক শর্তের উপর ভিত্তি করে সিদ্ধান্ত নেওয়া যায়।
and: সমস্ত শর্ত সত্য হলে সত্য হয়।
(and true true) ; আউটপুট: true (and true false) ; আউটপুট: falseor: যে কোনো একটি শর্ত সত্য হলে সত্য হয়।
(or false true) ; আউটপুট: true (or false false) ; আউটপুট: false
সারসংক্ষেপ
ক্লোজারে if, when, cond, case, and, এবং or এর মাধ্যমে বিভিন্ন শর্ত অনুযায়ী কার্যকরী সিদ্ধান্ত নেওয়া যায়। এই কন্ডিশনাল স্টেটমেন্টগুলো কোডিংকে আরও কার্যকর ও নমনীয় করে তোলে।
Clojure-এ if, when, এবং cond এর ব্যবহার
ক্লোজারে শর্ত নির্ধারণের জন্য বেশ কিছু অপশন আছে, তার মধ্যে if, when, এবং cond সবচেয়ে সাধারণ এবং বহুল ব্যবহৃত। এগুলো শর্ত অনুযায়ী কোডের প্রবাহ নিয়ন্ত্রণ করতে সহায়ক। এই তিনটি অপশনের কাজ, ব্যবহারের পদ্ধতি, এবং উদাহরণ নিচে আলোচনা করা হলো:
১. if ফাংশন
if ফাংশন একটি সাধারণ কন্ডিশনাল স্টেটমেন্ট, যা একটি একক শর্ত চেক করে। যদি শর্তটি সত্য হয়, তাহলে এটি প্রথম এক্সপ্রেশনটি রিটার্ন করে, আর মিথ্যা হলে দ্বিতীয় এক্সপ্রেশনটি রিটার্ন করে।
উদাহরণ
(defn check-even [n]
(if (even? n)
"Even"
"Odd"))
(check-even 4) ; আউটপুট: "Even"
(check-even 5) ; আউটপুট: "Odd"এখানে, check-even ফাংশনটি একটি সংখ্যা n চেক করে যে এটি সোজা (even) নাকি বিচ্ছিন্ন (odd)। যদি n সোজা হয়, তাহলে "Even" রিটার্ন করে, অন্যথায় "Odd" রিটার্ন করে।
২. when ফাংশন
when ফাংশন একটি শর্ত চেক করে এবং যদি শর্তটি সত্য হয়, তবে এক বা একাধিক এক্সপ্রেশন চালায়। এটি সাধারণত তখন ব্যবহৃত হয় যখন একাধিক কাজ করতে হয় যদি শর্তটি সত্য হয়। তবে, শর্তটি মিথ্যা হলে এটি কিছুই রিটার্ন করে না।
উদাহরণ
(defn print-positive [n]
(when (pos? n)
(println "The number is positive.")
(println "Positive numbers are greater than zero.")))
(print-positive 5)
; আউটপুট:
; "The number is positive."
; "Positive numbers are greater than zero."
(print-positive -3)
; আউটপুট: কিছুই নাএখানে, print-positive ফাংশনটি n এর মান ধনাত্মক কিনা চেক করে। যদি n ধনাত্মক হয়, তাহলে এটি দুটি বার্তা প্রিন্ট করে। কিন্তু যদি n নেতিবাচক হয়, তাহলে কিছুই প্রিন্ট করবে না।
৩. cond ফাংশন
cond একটি কন্ডিশনাল স্টেটমেন্ট যেখানে একাধিক শর্ত পরীক্ষা করা হয়। এটি অনেকগুলো if-else শর্ত একসাথে চেক করতে সাহায্য করে। প্রতিটি শর্ত এবং সংশ্লিষ্ট এক্সপ্রেশন পেয়ার আকারে থাকে এবং প্রথম যে শর্ত সত্য হয়, সেটির সাথে মিলিত এক্সপ্রেশনটি রিটার্ন হয়।
উদাহরণ
(defn categorize-number [n]
(cond
(neg? n) "Negative"
(zero? n) "Zero"
(pos? n) "Positive"))
(categorize-number -5) ; আউটপুট: "Negative"
(categorize-number 0) ; আউটপুট: "Zero"
(categorize-number 10) ; আউটপুট: "Positive"এখানে, categorize-number ফাংশনটি n এর মান অনুযায়ী তিনটি শর্ত চেক করে: নেতিবাচক, শূন্য, এবং ধনাত্মক। প্রথম যে শর্ত সত্য হয়, সেটির সংশ্লিষ্ট মান রিটার্ন হয়।
সারসংক্ষেপ: if, when, এবং cond এর পার্থক্য ও ব্যবহার
| ফাংশন | ব্যবহারের উদ্দেশ্য | কিভাবে কাজ করে |
|---|---|---|
if | একটি একক শর্ত চেক করার জন্য ব্যবহৃত হয় | শর্ত সত্য হলে প্রথম এক্সপ্রেশন, মিথ্যা হলে দ্বিতীয় |
when | একটি শর্ত সত্য হলে একাধিক এক্সপ্রেশন চালায় | শর্ত মিথ্যা হলে কিছুই রিটার্ন করে না |
cond | একাধিক শর্ত চেক করার জন্য ব্যবহৃত হয় | প্রথম যে শর্ত সত্য হয়, সেটির এক্সপ্রেশন চালায় |
এই ফাংশনগুলো শর্ত অনুযায়ী কোডের প্রবাহ নিয়ন্ত্রণ করতে ব্যবহৃত হয় এবং বিভিন্ন পরিস্থিতিতে বিভিন্ন ধরনের লজিক প্রয়োগ করতে সহায়ক।
Boolean Expressions এবং Short-Circuit Evaluation
ক্লোজারে (Clojure) বুলিয়ান এক্সপ্রেশন এবং শর্ট-সার্কিট ইভ্যালুয়েশন (Short-Circuit Evaluation) প্রোগ্রামিংয়ের গুরুত্বপূর্ণ অংশ। বুলিয়ান এক্সপ্রেশন হল এমন এক্সপ্রেশন যা true বা false হিসেবে মূল্যায়ন করে। শর্ট-সার্কিট ইভ্যালুয়েশন একটি অপ্টিমাইজেশন কৌশল, যেখানে নির্দিষ্ট শর্ত মিট হলে বাকি অংশ মূল্যায়ন না করেই এক্সপ্রেশন শেষ হয়।
Boolean Expressions
ক্লোজারে, বুলিয়ান এক্সপ্রেশন সাধারণত true বা false ভ্যালু প্রদান করে এবং সাধারণ লজিক্যাল অপারেটর ব্যবহার করে তৈরি করা হয়, যেমন and, or, এবং not। ক্লোজারে nil এবং false ছাড়া সবকিছু সত্যি (truthy) হিসেবে বিবেচিত হয়।
উদাহরণ: বুলিয়ান এক্সপ্রেশন
(def age 20)
(def adult? (>= age 18)) ; age যদি 18 বা তার বেশি হয়, তাহলে adult? হবে trueএখানে >= অপারেটর ব্যবহার করে adult? ভ্যারিয়েবলের মান নির্ধারণ করা হয়েছে। age যদি ১৮ বা তার বেশি হয়, তাহলে adult? এর মান হবে true অন্যথায় false।
Short-Circuit Evaluation
শর্ট-সার্কিট ইভ্যালুয়েশন এমন একটি কৌশল যেখানে লজিক্যাল অপারেটরের প্রথম অংশেই এক্সপ্রেশনের ফলাফল নির্ধারণ করা গেলে, পরবর্তী অংশগুলিকে আর মূল্যায়ন করা হয় না। ক্লোজারে and এবং or অপারেটর এই শর্ট-সার্কিট ইভ্যালুয়েশন প্রক্রিয়া অনুসরণ করে।
and অপারেটর এবং Short-Circuit Evaluation
and অপারেটর তখনই true রিটার্ন করে যখন সব এক্সপ্রেশন সত্য হয়। প্রথম কোনো এক্সপ্রেশন false হলে, বাকি অংশগুলি মূল্যায়ন করা হয় না, কারণ একবার false পাওয়া গেলে ফলাফলও false হবে।
(defn check-age-and-status [age status]
(and (>= age 18) (= status "active")))
(check-age-and-status 20 "active") ; আউটপুট: true
(check-age-and-status 15 "active") ; আউটপুট: false, কারণ প্রথম শর্তই falseএখানে, (>= age 18) শর্তটি false হলে (= status "active") পরীক্ষা করা হয় না, যা শর্ট-সার্কিট ইভ্যালুয়েশনের উদাহরণ।
or অপারেটর এবং Short-Circuit Evaluation
or অপারেটর তখনই true রিটার্ন করে যখন অন্তত একটি এক্সপ্রেশন সত্য হয়। প্রথম কোনো এক্সপ্রেশন true হলে, বাকি অংশগুলি মূল্যায়ন করা হয় না, কারণ প্রথম true ভ্যালু পেলেই ফলাফলও true হবে।
(defn check-permission [role permission]
(or (= role "admin") (= permission "granted")))
(check-permission "admin" "denied") ; আউটপুট: true, কারণ প্রথম শর্ত true
(check-permission "user" "granted") ; আউটপুট: true, কারণ দ্বিতীয় শর্ত true
(check-permission "user" "denied") ; আউটপুট: falseএখানে, role যদি "admin" হয়, তাহলে পরবর্তী শর্ত (= permission "granted") মূল্যায়ন করার প্রয়োজন হয় না, কারণ or অপারেটর প্রথম শর্ত true পেলেই true রিটার্ন করে।
not অপারেটর
not অপারেটর একটি একক বুলিয়ান এক্সপ্রেশনকে উল্টো মান প্রদান করে। এটি true কে false এবং false কে true করে।
(def logged-in false)
(def guest? (not logged-in)) ; আউটপুট: trueএখানে logged-in ভ্যারিয়েবলের মান false হওয়ায় guest? হবে true।
শর্ট-সার্কিট ইভ্যালুয়েশনের সুবিধাসমূহ
- পারফরম্যান্স অপ্টিমাইজেশন: অপ্রয়োজনীয় এক্সপ্রেশন মূল্যায়ন না করার কারণে কোডের পারফরম্যান্স উন্নত হয়।
- নিরাপদ অপারেশন: যখন ডিভিশন বা নাল চেকের মতো শর্ত থাকে, শর্ট-সার্কিট ইভ্যালুয়েশন ব্যবহার করে এড়ানো যায়।
- সহজ শর্ত: কমপ্লেক্স শর্তের মূল্যায়ন শর্ট-সার্কিটের মাধ্যমে সহজ হয়।
সারসংক্ষেপ
| অপারেটর | কাজ | শর্ট-সার্কিটের ধরন |
|---|---|---|
and | সব এক্সপ্রেশন সত্য হলে true | প্রথম false পেলে বাকি অংশ ইভ্যালুয়েট হয় না |
or | কোনো একটি এক্সপ্রেশন সত্য হলে true | প্রথম true পেলে বাকি অংশ ইভ্যালুয়েট হয় না |
not | এক্সপ্রেশন উল্টায় | শুধু একক এক্সপ্রেশনে ব্যবহৃত হয় |
ক্লোজারে বুলিয়ান এক্সপ্রেশন এবং শর্ট-সার্কিট ইভ্যালুয়েশন কার্যকর শর্ত নির্ধারণ ও অপ্টিমাইজেশনের জন্য গুরুত্বপূর্ণ এবং প্রোগ্রামিংকে আরও কার্যকর ও সুরক্ষিত করে।
Complex Conditions in Clojure with case and condp
In Clojure, both case and condp are used to handle conditional branching, but they have different use cases and are particularly useful for handling complex conditions. case is suitable for simple value-based matches, while condp allows more flexibility with complex predicates. Here’s a detailed look at how to use both in scenarios requiring more complex conditions.
Using case for Simple Value-Based Matching
The case expression in Clojure performs conditional branching based on exact matches for specific values. It is optimized for performance but does not support complex predicates or ranges.
Example: Using case for Matching Specific Values
(defn describe-grade [grade]
(case grade
"A" "Excellent"
"B" "Good"
"C" "Average"
"D" "Below Average"
"F" "Fail"
"Unknown grade"))
(describe-grade "A") ; Output: "Excellent"
(describe-grade "E") ; Output: "Unknown grade"In this example, case is ideal because each grade corresponds to an exact match. However, it is limited in cases where you need to evaluate complex conditions (e.g., ranges, comparisons). For such cases, condp is more flexible.
Using condp for Complex Condition Matching
The condp macro is more flexible than case because it allows you to specify a predicate function and compare each value with the predicate. This is particularly useful when you have multiple conditions that aren’t based on simple value matches, such as ranges or other conditions requiring functions.
Syntax of condp
(condp predicate test-expr
value1 result1
value2 result2
...
:else default-result)Here, predicate is the function applied to test-expr and each value. If the predicate returns true, the corresponding result is executed.
Example: Using condp for Ranges
Suppose we want to categorize age ranges:
(defn age-category [age]
(condp <= age
13 "Child"
18 "Teenager"
65 "Adult"
"Senior"))
(age-category 10) ; Output: "Child"
(age-category 15) ; Output: "Teenager"
(age-category 40) ; Output: "Adult"
(age-category 70) ; Output: "Senior"Here, the <= predicate compares age against each boundary. If age is less than or equal to 13, it’s a "Child". If age is greater than 13 but less than or equal to 18, it’s a "Teenager", and so on.
Example: Using condp with Custom Conditions
We can also use condp with a custom predicate, such as contains? for checking if a value is part of a set:
(defn animal-type [animal]
(condp contains? animal
#{"dog" "cat" "hamster"} "Pet"
#{"lion" "tiger" "bear"} "Wild Animal"
#{"chicken" "cow" "goat"} "Farm Animal"
"Unknown"))
(animal-type "dog") ; Output: "Pet"
(animal-type "lion") ; Output: "Wild Animal"
(animal-type "chicken") ; Output: "Farm Animal"
(animal-type "whale") ; Output: "Unknown"In this example, condp with contains? helps us group animals into categories based on set membership.
Comparing case and condp
| Feature | case | condp |
|---|---|---|
| Usage | Simple, exact matches | Complex conditions, predicates |
| Best For | Value-based cases, enums | Ranges, sets, custom conditions |
| Limitations | No complex conditions, only exact matches | Slightly less performant, but flexible |
Summary
caseis ideal for simple value-based matches where each condition is an exact value.condpis highly flexible and suitable for complex conditions, ranges, and other predicate-based comparisons.
Both case and condp help manage complex conditional logic in Clojure and make code more readable and efficient by avoiding nested if and cond statements.
কন্ডিশনাল ডেটা ম্যানিপুলেশন
ক্লোজার (Clojure) প্রোগ্রামিং ভাষায় কন্ডিশনাল ডেটা ম্যানিপুলেশন এমন একটি কৌশল যেখানে নির্দিষ্ট শর্ত (condition) অনুযায়ী ডেটা ম্যানিপুলেট (পরিবর্তন) করা হয়। এটি সাধারণত if, cond, when, এবং case ফাংশন ব্যবহার করে করা হয়, যা শর্ত নির্ধারণের মাধ্যমে কোডের প্রবাহ নিয়ন্ত্রণ করে।
ক্লোজারে শর্তাধীন ডেটা ম্যানিপুলেশন খুবই গুরুত্বপূর্ণ, কারণ এটি ডেটা প্রক্রিয়াকরণে কার্যকরী সিদ্ধান্ত নেওয়ার জন্য সাহায্য করে।
১. if ফাংশন
if ফাংশন ব্যবহার করে একটি শর্তের ভিত্তিতে দুটি ভিন্ন ফলাফল অর্জন করা যায়। এটি সাধারণত একক শর্তের জন্য ব্যবহৃত হয়।
উদাহরণ: if ব্যবহারে কন্ডিশনাল ম্যানিপুলেশন
(defn check-even [n]
(if (even? n)
"Even"
"Odd"))
(check-even 4) ; আউটপুট: "Even"
(check-even 5) ; আউটপুট: "Odd"এখানে, check-even ফাংশনটি পরীক্ষা করে যে সংখ্যাটি সোজা (even) না বিচ্ছিন্ন (odd)। যদি সংখ্যা সোজা হয়, তাহলে "Even" আউটপুট হয়, অন্যথায় "Odd"।
২. cond ফাংশন
cond একটি শক্তিশালী কন্ডিশনাল ফাংশন যা একাধিক শর্ত পরীক্ষা করতে ব্যবহৃত হয়। এটি মূলত অনেকগুলো if-else শর্ত একসাথে চেক করতে সাহায্য করে।
উদাহরণ: cond ব্যবহারে কন্ডিশনাল ম্যানিপুলেশন
(defn categorize-number [n]
(cond
(neg? n) "Negative"
(zero? n) "Zero"
(pos? n) "Positive"))
(categorize-number -5) ; আউটপুট: "Negative"
(categorize-number 0) ; আউটপুট: "Zero"
(categorize-number 10) ; আউটপুট: "Positive"এখানে, categorize-number ফাংশনটি তিনটি শর্ত পরীক্ষা করে: নেতিবাচক (negative), শূন্য (zero), এবং ধনাত্মক (positive)। cond ফাংশনটি একাধিক শর্তের জন্য সহজেই কাজ করতে সাহায্য করে।
৩. when এবং when-not ফাংশন
when এবং when-not ফাংশন দুটি শর্তাধীন স্টেটমেন্ট যেখানে কোনো শর্ত সত্য হলে একটি একক এক্সপ্রেশন কার্যকর হয়। when শুধুমাত্র শর্ত সত্য হলে কাজ করে এবং when-not শর্ত মিথ্যা হলে কাজ করে।
উদাহরণ: when এবং when-not ব্যবহারে কন্ডিশনাল ম্যানিপুলেশন
(defn print-positive [n]
(when (pos? n)
(println "Positive number")))
(print-positive 10) ; আউটপুট: "Positive number"
(print-positive -5) ; আউটপুট: কিছুই না
(defn print-negative [n]
(when-not (pos? n)
(println "Non-positive number")))
(print-negative -5) ; আউটপুট: "Non-positive number"
(print-negative 10) ; আউটপুট: কিছুই নাএখানে, print-positive ফাংশনটি n যদি ধনাত্মক হয় তবে "Positive number" প্রিন্ট করবে, অন্যথায় কিছু করবে না। print-negative ফাংশনটি n যদি নেতিবাচক বা শূন্য হয় তবে "Non-positive number" প্রিন্ট করবে।
৪. case ফাংশন
case একটি আরও উন্নত কন্ডিশনাল ফাংশন, যা অনেকগুলো শর্ত পরীক্ষা করে এবং নির্দিষ্ট মানের সাথে মিলে গেলে কার্যকর হয়। এটি সাধারণত switch কন্ডিশনের মতো ব্যবহৃত হয়।
উদাহরণ: case ব্যবহারে কন্ডিশনাল ম্যানিপুলেশন
(defn describe-day [day]
(case day
"Monday" "Start of the week"
"Friday" "End of the work week"
"Sunday" "Relaxing day"
"Unknown day"))
(describe-day "Monday") ; আউটপুট: "Start of the week"
(describe-day "Friday") ; আউটপুট: "End of the work week"
(describe-day "Saturday") ; আউটপুট: "Unknown day"এখানে, describe-day ফাংশনটি একাধিক দিন পরীক্ষার মাধ্যমে আউটপুট প্রদান করে। case ফাংশনটি সহজে একাধিক শর্ত চেক করতে সাহায্য করে এবং এই উদাহরণে day এর মান অনুযায়ী একটি উপযুক্ত বার্তা প্রদান করে।
সারসংক্ষেপ
ক্লোজারে কন্ডিশনাল ডেটা ম্যানিপুলেশন করার জন্য বেশ কিছু শক্তিশালী কৌশল উপলব্ধ:
| ফাংশন | ব্যবহার | উদাহরণ |
|---|---|---|
if | একক শর্ত চেক করার জন্য | if (even? n) "Even" "Odd" |
cond | একাধিক শর্ত পরীক্ষা করার জন্য | cond দিয়ে একাধিক শর্ত চেক করা |
when | একটি শর্ত সত্য হলে এক্সপ্রেশন চালানো | when (pos? n) (println "Positive") |
case | একাধিক মানের মধ্যে সঠিক মান চেক করা | case day দিয়ে বিভিন্ন দিনের বর্ণনা |
এই ফাংশনগুলো শর্তাধীন সিদ্ধান্ত নেয়ার জন্য ক্লোজারকে আরও শক্তিশালী এবং নমনীয় করে তোলে।
Read more