LISP একটি কন্ট্রোল স্ট্রাকচার হিসেবে catch, throw, এবং handler-case প্রদান করে, যা আপনাকে এক্সসেপশন হ্যান্ডলিং এবং অতিপ্রতিক্রিয়া (exception handling) বা কন্ট্রোল ফ্লো পরিচালনা করতে সহায়ক। এগুলি সাধারণত কোডের ভেতরে অবাঞ্ছিত বা অপ্রত্যাশিত পরিস্থিতির জন্য ব্যবহৃত হয় এবং সেগুলিকে এক্সসেপশন হিসাবে ক্যাচ (ধরা) করে বিভিন্ন প্রতিক্রিয়া তৈরি করা হয়।
১. catch এবং throw
catch এবং throw LISP-এ এক্সসেপশন হ্যান্ডলিংয়ের জন্য ব্যবহৃত হয় এবং সিদ্ধান্ত নেওয়ার জন্য নিয়ন্ত্রণ পদ্ধতি সরবরাহ করে। এখানে catch ফাংশন একটি ব্লক তৈরি করে যা throw ফাংশন দ্বারা চালিত হয়।
catch ফাংশন
catch একটি বিশেষ পদ্ধতি যা একটি লেবেল দিয়ে একটি ব্লক তৈরি করে, যাতে যখন আপনি throw ফাংশন ব্যবহার করে নির্দিষ্ট লেবেলটি আছড়ে ফেলবেন, তখন কোড ওই ব্লকের মধ্যে চলে আসে। এই পদ্ধতি কোডের নিয়ন্ত্রণ পুনঃস্থাপন করতে ব্যবহৃত হয়।
throw ফাংশন
throw ফাংশনটি একটি লেবেল এবং একটি মান গ্রহণ করে এবং যখন এটি কল করা হয়, তখন এটি catch ব্লকের মধ্যে ওই লেবেলকে থ্রো (পাঠানো) করে, এবং সেই লেবেলের সাথে সম্পর্কিত কোডের অংশটি আবার কার্যকর হয়। এটি এক ধরনের এর্লি রিটার্ন বা ইরর প্রপাগেশন হিসাবে কাজ করে।
উদাহরণ:
(defun test-catch-throw ()
(catch 'my-label
(format t "Before throw~%")
(throw 'my-label 'exit)
(format t "After throw~%"))) ; এই লাইনটি কখনোই কার্যকর হবে না
(test-catch-throw)আউটপুট:
Before throwএখানে catch ব্লক একটি লেবেল my-label তৈরি করেছে, এবং পরে throw সেই লেবেলটি থ্রো করার মাধ্যমে কন্ট্রোল পুনঃস্থাপন করেছে। এই কারণে, throw ফাংশনটি catch ব্লকের বাইরে চলে যেতে সহায়ক হয়েছে এবং "After throw" কখনওই প্রিন্ট হয়নি।
২. handler-case
handler-case হল একটি আরও সাধারণ ও নমনীয় পদ্ধতি, যা এক্সসেপশন হ্যান্ডলিংয়ের জন্য ব্যবহৃত হয়। এটি ক্যাচ ব্লকের মতো কাজ করে, তবে এখানে এক্সসেপশনটি ধরা হলে বিভিন্ন প্রতিক্রিয়া বা হ্যান্ডলার কার্যকরী করা যেতে পারে, যা এক্সসেপশন ধরার পর নির্দিষ্ট কাজ করতে পারে।
handler-case একটি এক্সপ্রেশন গ্রহণ করে এবং এটি একাধিক হ্যান্ডলারের মাধ্যমে বিভিন্ন ধরণের এক্সসেপশন মোকাবিলা করতে পারে।
সিনট্যাক্স:
(handler-case expression
(condition-type (lambda () action))
(condition-type2 (lambda () action2)))expression: যা এক্সপ্রেশনটি চলবে।condition-type: এক্সসেপশন ধরা হবে যে ধরনের (যেমন,error,warningইত্যাদি)।action: এক্সসেপশন ধরা হলে যা কার্যকর হবে।
উদাহরণ:
(handler-case
(progn
(format t "Before exception~%")
(error "An error occurred")) ; একটি ইরর ঘটানো হচ্ছে
(error (lambda () (format t "Caught an error~%"))))আউটপুট:
Before exception
Caught an errorএখানে, handler-case একটি error এক্সসেপশন ধরেছে এবং এর জন্য একটি নির্দিষ্ট lambda ফাংশন চালানো হয়েছে, যা "Caught an error" প্রিন্ট করেছে।
উদাহরণ: একাধিক এক্সসেপশন হ্যান্ডলিং
(handler-case
(/ 10 0) ; জিরো দিয়ে ভাগ করা হচ্ছে, যা ডিভিশন বাই জিরো এক্সসেপশন তৈরি করবে
(division-by-zero (lambda () (format t "Cannot divide by zero~%"))))আউটপুট:
Cannot divide by zeroএখানে, handler-case ব্যবহার করা হয়েছে যাতে division-by-zero এক্সসেপশনটি ধরা পড়ে এবং ব্যবহারকারীকে উপযুক্ত বার্তা দেওয়া হয়।
৩. handler-bind
handler-bind একটি অন্যান্য বিকল্প যা এক্সসেপশন হ্যান্ডলিংয়ের জন্য ব্যবহৃত হয় এবং এটি অনেকটা handler-case এর মতো কাজ করে। তবে, handler-bind আপনাকে একাধিক এক্সসেপশন হ্যান্ডলারকে একসাথে ব্যবহার করতে সুযোগ দেয় এবং এটি সাধারণত কমপ্লেক্স এক্সসেপশন হ্যান্ডলিং সিস্টেমে ব্যবহৃত হয়।
উদাহরণ:
(handler-bind ((error #'(lambda (c) (format t "Error: ~A~%" c))))
(error "This is a custom error"))এখানে, error হ্যান্ডলারটি handler-bind এর মাধ্যমে ব্যবহৃত হয়েছে এবং একটি কাস্টম বার্তা দেখিয়েছে।
সারসংক্ষেপ
LISP-এ catch, throw, এবং handler-case ফাংশনগুলো এক্সসেপশন হ্যান্ডলিং এবং কন্ট্রোল ফ্লো ব্যবস্থাপনার জন্য গুরুত্বপূর্ণ উপাদান:
catchএবংthrow: এক্সসেপশন বা কন্ট্রোল ফ্লো পরিবর্তন করতে ব্যবহৃত হয়।catchব্লক একটি লেবেল দিয়ে কোডের নিয়ন্ত্রণ পদ্ধতি তৈরি করে এবংthrowলেবেলটি থ্রো (প্রেরণ) করে।handler-case: এক্সসেপশন হ্যান্ডলিংয়ের জন্য ব্যবহৃত হয়, যেখানে বিভিন্ন এক্সসেপশন টাইপের জন্য বিভিন্ন হ্যান্ডলার ফাংশন দেওয়া যেতে পারে।handler-bind: একাধিক এক্সসেপশন হ্যান্ডলার পরিচালনা করতে ব্যবহৃত হয়।
এগুলো একসাথে ব্যবহার করে, আপনি আপনার LISP প্রোগ্রামগুলোতে এক্সসেপশন হ্যান্ডলিং, কন্ট্রোল ফ্লো পরিবর্তন এবং কার্যকরী কোড গঠন করতে পারবেন।
Read more