LISP একটি হাই-লেভেল ফাংশনাল প্রোগ্রামিং ভাষা, যেখানে Macros একটি অত্যন্ত শক্তিশালী বৈশিষ্ট্য হিসেবে ব্যবহৃত হয়। defmacro একটি macro definition ফাংশন, যা LISP কোডের ম্যাক্রো তৈরি করতে ব্যবহৃত হয়। Macros আপনাকে কোড জেনারেট বা কাস্টম সিনট্যাক্স তৈরি করতে দেয়, যা পরে স্বাভাবিক ফাংশন বা এক্সপ্রেশন হিসেবে ব্যবহার করা হয়।
ম্যাক্রোস সাধারণত compile-time এ কাজ করে এবং code transformations এর জন্য ব্যবহৃত হয়। LISP এর defmacro এর মাধ্যমে আপনি এমন কোড তৈরি করতে পারেন যা রানটাইমে পরিবর্তন করার জন্য প্রোগ্রামারকে অধিক নিয়ন্ত্রণ দেয়।
১. defmacro (Macro Definition)
defmacro একটি বিশেষ ফাংশন, যা নতুন একটি ম্যাক্রো ডিফাইন করে। এটি ফাংশনাল প্রোগ্রামিংয়ের মধ্যে কোড তৈরির একটি ফর্ম হিসেবে ব্যবহৃত হয়। ম্যাক্রো ফাংশনগুলোর মধ্যে পার্থক্য হল, ম্যাক্রো ব্লকের সময় (compile-time) চলার সময় কোডকে প্রসারিত বা পরিবর্তন করতে পারে, যখন ফাংশন রানটাইমে কার্যকরী হয়।
Syntax of defmacro:
(defmacro macro-name (parameters)
"Macro body"
body)এখানে:
- macro-name: ম্যাক্রোর নাম
- parameters: ম্যাক্রোর আর্গুমেন্টস
- body: ম্যাক্রোর কার্যকলাপ বা কোড এক্সপ্রেশন
উদাহরণ:
(defmacro square (x)
`(* ,x ,x)) ; ,x ব্যবহার করা হচ্ছে এক্সপ্রেশনের মান অ্যাক্সেস করার জন্যএখানে, square একটি ম্যাক্রো তৈরি করা হয়েছে যা তার ইনপুট x এর স্কোয়ার (গুণফল) প্রদান করবে।
২. Macro Expansion (ম্যাক্রোর সম্প্রসারণ)
ম্যাক্রো expansion হল কোডের প্রসারণ প্রক্রিয়া, যেখানে একটি ম্যাক্রো তার ডিফাইন্ড কন্টেন্টে এক্সপ্যান্ড (বিস্তৃত) হয়। ম্যাক্রো যখন কল করা হয়, তখন তার শরীরের কোড এক্সপ্র্যান্ড হয় (বর্ধিত হয়) এবং এক্সপ্রেশনটি একটি নতুন ফর্মে রেন্ডার হয়।
এটি একটি ম্যাক্রোর কার্যকারিতা। ম্যাক্রোর মূল কাজ হলো, এটি কোডের কিছু অংশের পরিবর্তে একটি নতুন কোড এক্সপ্রেশন ইনসার্ট করে, যেটি compile-time এ ঘটে।
উদাহরণ (Macro Expansion):
(defmacro square (x)
`(* ,x ,x))
(square 5) ; আউটপুট: (* 5 5)এখানে, square ম্যাক্রো যখন কল করা হয়, তখন এটি (* 5 5) রূপে এক্সপ্যান্ড হয়। এর ফলে, ম্যাক্রোর কলের সময় কোডকে প্রসারিত করা হয়েছে।
৩. এক্সপ্রেশনের মধ্যে ম্যাক্রো ব্যবহার
ম্যাক্রো ব্যবহার করার সময়, এর expansion এবং evaluation এর মধ্যে কিছু পার্থক্য থাকে। যখন আপনি defmacro দিয়ে ম্যাক্রো ডিফাইন করেন, তখন তার সঠিক এক্সপ্যানশন এবং ফলাফলগুলি কম্পাইল টাইমে ঘটে।
উদাহরণ:
(defmacro add-squares (a b)
`(+ (square ,a) (square ,b)))
(add-squares 3 4)এখানে, add-squares ম্যাক্রো দুটি ইনপুট নেবে এবং তাদের স্কোয়ার যোগফল করবে। ম্যাক্রোর expansion হবে:
(+ (square 3) (square 4)) ; পরবর্তীতে: (+ (* 3 3) (* 4 4))এই expansion এর মাধ্যমে add-squares একটি নতুন এক্সপ্রেশন তৈরি করছে, যা দুইটি square কলকে যোগ করছে। Macro expansion এ, কোডটি কনভার্ট হয়ে যাওয়া এক্সপ্রেশনটি তখন রানটাইমে কার্যকরী হবে।
৪. Macros vs Functions
- Functions: ফাংশন শুধুমাত্র ইনপুট আর্গুমেন্ট গ্রহণ করে এবং রানটাইমে সেই আর্গুমেন্টের উপর কাজ করে। ফাংশন কোডটি রানটাইমে এক্সিকিউট হয়।
- Macros: ম্যাক্রো কোডটি compile-time এ প্রসারিত (expand) হয়ে নতুন কোড তৈরি করে, যা পরবর্তীতে রানটাইমে কার্যকরী হয়।
এখানে একটি ফাংশন এবং ম্যাক্রোর মধ্যে পার্থক্য দেখা যাচ্ছে:
(defun square-function (x)
(* x x)) ; ফাংশন
(defmacro square-macro (x)
`(* ,x ,x)) ; ম্যাক্রোsquare-function ফাংশনটি রানটাইমে কাজ করবে, কিন্তু square-macro ম্যাক্রোটি compile-time এ এক্সপ্যান্ড হবে এবং তার পরে যে কোডটি তৈরি হবে, তা রানটাইমে এক্সিকিউট হবে।
৫. অপারেশনাল ম্যাক্রো
লিস্টে ম্যাক্রোর কার্যকারিতা ব্যাখ্যা করার জন্য কিছু গুরুত্বপূর্ণ ব্যবহার করা যেতে পারে, যেমন:
- লজিক্যাল পরীক্ষণ: বিভিন্ন অপারেশন এবং শর্ত পরীক্ষণের জন্য ম্যাক্রো ব্যবহৃত হয়।
- এনক্যাপসুলেশন: কোডের নির্দিষ্ট অংশকে ইনক্যাপসুলেট করা এবং পুনঃব্যবহারযোগ্য কোড তৈরি করার জন্য ম্যাক্রো ব্যবহার হয়।
- ডিবাগিং: ম্যাক্রোর মাধ্যমে কোডের আউটপুট সহজেই প্রিন্ট করা বা পরীক্ষা করা যায়।
সারসংক্ষেপ
defmacroএকটি ম্যাক্রো ডিফাইন করে, যা compile-time এ প্রসারিত (expand) হয়।- Macro Expansion হল ম্যাক্রোর প্রসারণ প্রক্রিয়া, যেখানে একটি ম্যাক্রো তার শরীরের কোডে এক্সপ্যান্ড হয়।
- ম্যাক্রো compile-time এ কার্যকরী হয়, যা আপনাকে কোডকে পরিবর্তন এবং কাস্টমাইজ করার অধিক ক্ষমতা দেয়।
- ম্যাক্রো এবং ফাংশনের মধ্যে প্রধান পার্থক্য হলো, ম্যাক্রো compile-time এ প্রসারিত হয়ে নতুন কোড তৈরি করে, যেখানে ফাংশন runtime এ এক্সিকিউট হয়।
LISP এ macros কোডের শক্তিশালী কাস্টমাইজেশন, ট্রান্সফরমেশন, এবং metaprogramming এর জন্য একটি অত্যন্ত গুরুত্বপূর্ণ বৈশিষ্ট্য।
Read more