LISP ভাষায় ভেরিয়েবলস এবং বাইন্ডিংস একটি গুরুত্বপূর্ণ কনসেপ্ট। LISP-এ ভেরিয়েবলস সাধারণত নাম হিসেবে কাজ করে, যা কোনো মান বা ডেটা ধারণ করে। বাইন্ডিংস হল সেই প্রক্রিয়া যার মাধ্যমে একটি ভেরিয়েবলকে একটি নির্দিষ্ট মান (value) এর সাথে যুক্ত (bind) করা হয়।
LISP-এ ভেরিয়েবলস এবং বাইন্ডিংস মূলত দুইটি প্রধান প্রক্রিয়া অনুসরণ করে: ডাইনামিক বাইন্ডিং (Dynamic Binding) এবং **স্ট্যাটিক বাইন্ডিং (Static Binding)**। তবে, LISP তে সাধারণত ডাইনামিক বাইন্ডিং ব্যবহৃত হয়। এখানে LISP-এ ভেরিয়েবলস এবং বাইন্ডিংস সম্পর্কে বিস্তারিত আলোচনা করা হয়েছে।
১. ভেরিয়েবল (Variable)
LISP-এ ভেরিয়েবল হলো একটি নাম, যা কোনো মান বা ডেটা ধারণ করে। একটি ভেরিয়েবল মূলত একটি স্থান (location) যেখানে একটি নির্দিষ্ট মান রাখা হয়।
ভেরিয়েবল তৈরি এবং সেট করার জন্য LISP-এ দুটি প্রধান কিওয়ার্ড রয়েছে:
setq: এটি একটি ভেরিয়েবলকে একটি মানের সাথে যুক্ত (bind) করতে ব্যবহৃত হয়।defvarএবংdefparameter: এগুলি একটি ভেরিয়েবল তৈরি করে এবং তার প্রাথমিক মান সেট করতে ব্যবহৃত হয়।
উদাহরণ:
(setq x 10) ; x ভেরিয়েবলকে 10 দিয়ে বাইন্ড করা
(setq y (+ x 5)) ; y ভেরিয়েবলকে x+5 মান দিয়ে বাইন্ড করাএখানে x এবং y দুটি ভেরিয়েবল, যেখানে x এর মান ১০ এবং y এর মান x+5 অর্থাৎ ১৫।
২. বাইন্ডিং (Binding)
বাইন্ডিং হচ্ছে একটি ভেরিয়েবলকে একটি নির্দিষ্ট মান বা ডেটার সাথে যুক্ত করা। যখন একটি ভেরিয়েবলকে একটি মান দেওয়া হয়, তখন সেটি বাইন্ডিং হিসেবে পরিচিত। LISP ভাষায়, বাইন্ডিং সাধারণত ডাইনামিক টাইপিংয়ের মাধ্যমে পরিচালিত হয়, যার মানে হল যে ভেরিয়েবলের মান পরিবর্তন করার সময় তার স্কোপ বা স্থানীয়তা খুবই গুরুত্বপূর্ণ।
বাইন্ডিং-এর উদাহরণ:
(setq a 5) ; a ভেরিয়েবলকে 5 দিয়ে বাইন্ড করা
(setq b (* a 2)) ; b ভেরিয়েবলকে a*2 মান দিয়ে বাইন্ড করাএখানে a এবং b দুটি ভেরিয়েবল এবং তাদের বাইন্ডিংয়ের মাধ্যমে তাদের মান নির্ধারণ করা হয়েছে।
৩. ডাইনামিক বাইন্ডিং (Dynamic Binding)
LISP ভাষায় সাধারণত ডাইনামিক বাইন্ডিং ব্যবহৃত হয়। এর মানে হল যে, একটি ভেরিয়েবল একটি নির্দিষ্ট স্কোপে মান গ্রহণ করতে পারে, কিন্তু ভেরিয়েবলের মান সেই স্কোপে পরিবর্তন করলে এটি অন্য স্কোপে প্রভাব ফেলতে পারে।
উদাহরণ:
(setq x 10) ; x ভেরিয়েবলকে 10 দিয়ে বাইন্ড করা
(defun example-function ()
(setq x 20) ; এখানে x-এর মান পরিবর্তন করা
(print x))
(example-function) ; আউটপুট: 20
(print x) ; আউটপুট: 20 (স্কোপের বাইরে x-এর মান পরিবর্তিত হয়েছে)এখানে x ভেরিয়েবলটি প্রথমে ১০ দিয়ে বাইন্ড করা হয়েছে, কিন্তু ফাংশন example-function এ এর মান পরিবর্তন করা হয়েছে ২০। এরপর যখন x এর মান বাইরে প্রিন্ট করা হয়েছে, তখন তার মান ২০ হয়ে গেছে, কারণ এটি ডাইনামিক বাইন্ডিং ব্যবহার করছে।
৪. স্ট্যাটিক বাইন্ডিং (Static Binding)
LISP তে সাধারণত স্ট্যাটিক বাইন্ডিং ব্যবহৃত হয় না, কিন্তু কিছু সংস্করণে বা নির্দিষ্ট পরিস্থিতিতে স্ট্যাটিক বাইন্ডিংও সম্ভব। স্ট্যাটিক বাইন্ডিং-এর মাধ্যমে, ভেরিয়েবলের মান একটি নির্দিষ্ট স্থানে (যেমন একটি ফাংশন) নির্দিষ্ট করা হয় এবং সেই স্থানের বাইরে পরিবর্তন করা যায় না।
৫. স্কোপ (Scope) এবং ভেরিয়েবল লাইফটাইম
LISP ভাষায় ভেরিয়েবলের স্কোপ এবং লাইফটাইম একটি গুরুত্বপূর্ণ বিষয়। ভেরিয়েবলটির মান বা বাইন্ডিং কেবল তার স্কোপের মধ্যে কার্যকর থাকে। এর মানে হল যে, যদি কোনো ভেরিয়েবল একটি ফাংশনের মধ্যে বাইন্ড করা হয়, তবে সেই ভেরিয়েবলটি ফাংশনের বাইরে অ্যাক্সেসযোগ্য হবে না।
স্কোপের উদাহরণ:
(setq a 100) ; গ্লোবাল স্কোপে a-এর মান সেট করা
(defun my-function ()
(setq a 50) ; স্থানীয় স্কোপে a-এর মান পরিবর্তন
(print a)) ; আউটপুট হবে 50
(my-function)
(print a) ; আউটপুট হবে 100 (গ্লোবাল স্কোপে a-এর মান অপরিবর্তিত)এখানে a গ্লোবাল স্কোপে বাইন্ড করা হয়েছে ১০০, তবে ফাংশন my-function এর মধ্যে এটি পরিবর্তিত হয়েছে ৫০। কিন্তু ফাংশনের বাইরে গ্লোবাল স্কোপে a এর মান অপরিবর্তিত রয়েছে, অর্থাৎ ডাইনামিক বাইন্ডিং এর মাধ্যমে স্থানীয় এবং গ্লোবাল মান আলাদা।
৬. ভেরিয়েবল বাইন্ডিং এর পদ্ধতি
LISP এ let এবং let* কিওয়ার্ড ব্যবহার করে স্থানীয় ভেরিয়েবল তৈরি এবং বাইন্ড করা যায়।
let: এটি এক বা একাধিক ভেরিয়েবলকে একটি নির্দিষ্ট মান দিয়ে বাইন্ড করে।let*: এটি একইভাবে কাজ করে, তবে একাধিক ভেরিয়েবলের মান একে একে বাইন্ড করা হয়, অর্থাৎ প্রথম ভেরিয়েবলের মান সেট হওয়ার পরে পরবর্তী ভেরিয়েবল সেট হয়।
উদাহরণ:
(let ((x 10)
(y 20))
(+ x y)) ; আউটপুট: 30এটি একটি let ব্লক, যেখানে x এবং y দুটি স্থানীয় ভেরিয়েবল বাইন্ড করা হয়েছে এবং তাদের যোগফল ৩০ রিটার্ন করা হয়েছে।
(let* ((x 10)
(y (+ x 5)))
(+ x y)) ; আউটপুট: 25এটি let* ব্লক, যেখানে y ভেরিয়েবলটি প্রথমে x এর মানের উপর নির্ভর করে বাইন্ড হয়েছে।
সারসংক্ষেপ
LISP ভাষায় ভেরিয়েবলস এবং বাইন্ডিংস একটি অত্যন্ত গুরুত্বপূর্ণ কনসেপ্ট। এখানে ভেরিয়েবলগুলি নাম হিসেবে কাজ করে এবং বাইন্ডিং এর মাধ্যমে তাদের মান নির্ধারণ করা হয়। LISP সাধারণত ডাইনামিক বাইন্ডিং ব্যবহার করে, যেখানে ভেরিয়েবলের মান পরিবর্তন হতে পারে এবং অন্যান্য স্কোপে প্রভাব ফেলতে পারে। let এবং let* কিওয়ার্ডগুলির মাধ্যমে স্থানীয় ভেরিয়েবল তৈরি এবং বাইন্ড করা হয়, যা কোডের কার্যকরীতা ও স্কোপ নিয়ন্ত্রণে সাহায্য করে।
LISP (LISt Processing) একটি ফাংশনাল প্রোগ্রামিং ভাষা হওয়ায়, এখানে ভেরিয়েবল ডিক্লারেশন এবং ইনিশিয়ালাইজেশন (অর্থাৎ ভেরিয়েবল সৃষ্টি ও তার প্রাথমিক মান নির্ধারণ) কিছুটা আলাদা হতে পারে। LISP-এ ভেরিয়েবলগুলো সাধারণত ডিক্লেয়ার করা হয় এবং তারপরে তাদের ইনিশিয়ালাইজ করা হয়, তবে LISP একটি ডায়নামিক্যালি টাইপড ভাষা হওয়ায় ভেরিয়েবলগুলোর টাইপ আগে থেকে নির্ধারণ করতে হয় না।
১. ভেরিয়েবল ডিক্লারেশন (Variable Declaration)
LISP-এ ভেরিয়েবল ডিক্লেয়ার করার জন্য setq, defvar, অথবা defparameter ফাংশন ব্যবহার করা হয়। যদিও LISP এ স্ট্যাটিক ডিক্লারেশন (যেমন C, Java বা অন্যান্য ভাষায় থাকে) নেই, তবুও ভেরিয়েবল তৈরি করতে হয়।
setq ফাংশন
setq হল LISP-এ ভেরিয়েবল সেট করার জন্য সবচেয়ে সাধারণ পদ্ধতি। এখানে প্রথমে ভেরিয়েবলের নাম এবং তারপর তার মান দেওয়া হয়।
উদাহরণ:
(setq x 10) ; x ভেরিয়েবলকে 10 দিয়ে ইনিশিয়ালাইজ করা হয়েছে
(setq y 20) ; y ভেরিয়েবলকে 20 দিয়ে ইনিশিয়ালাইজ করা হয়েছেএখানে setq দ্বারা ভেরিয়েবল x এবং y ডিক্লেয়ার এবং ইনিশিয়ালাইজ করা হয়েছে।
defvar এবং defparameter ফাংশন
defvarসাধারণত একবার ভেরিয়েবল ডিক্লেয়ার করার জন্য ব্যবহৃত হয়, যাতে এটি যদি পূর্বে ডিফাইন না করা থাকে তবে এটি ইনিশিয়ালাইজ হয়।defparameterএর ব্যবহারও একই, তবে এটি বারবার নতুন মান ইনিশিয়ালাইজ করার জন্য ব্যবহৃত হয়।
উদাহরণ:
(defvar z 30) ; z ভেরিয়েবলকে 30 দিয়ে ডিফাইন করা হয়েছে
(defparameter w 40) ; w ভেরিয়েবলকে 40 দিয়ে ডিফাইন করা হয়েছে২. ভেরিয়েবল ইনিশিয়ালাইজেশন (Variable Initialization)
ভেরিয়েবল ইনিশিয়ালাইজেশন মানে হচ্ছে কোনো ভেরিয়েবলের জন্য প্রথমবারের মতো মান নির্ধারণ করা। LISP-এ setq, defvar, এবং defparameter-এর মাধ্যমে ভেরিয়েবল ইনিশিয়ালাইজ করা হয়।
setq দিয়ে ইনিশিয়ালাইজেশন
যেমন আগে দেখানো হয়েছে, setq দিয়ে ভেরিয়েবল ডিক্লেয়ার এবং ইনিশিয়ালাইজ করা যায়। এটি মান সরাসরি নির্ধারণ করে।
উদাহরণ:
(setq a 100) ; a ভেরিয়েবলকে 100 দিয়ে ইনিশিয়ালাইজ
(setq b 50) ; b ভেরিয়েবলকে 50 দিয়ে ইনিশিয়ালাইজdefvar দিয়ে ইনিশিয়ালাইজেশন
defvar দিয়ে যদি ভেরিয়েবল ডিক্লেয়ার করা হয় এবং তার মান যদি ইতিমধ্যে ডিফাইন করা না থাকে, তাহলে এটি ইনিশিয়ালাইজ করা হবে।
উদাহরণ:
(defvar c 200) ; c ভেরিয়েবলকে 200 দিয়ে ইনিশিয়ালাইজdefparameter দিয়ে ইনিশিয়ালাইজেশন
defparameter ফাংশনটি যখন ব্যবহার করা হয়, তখন এটি ভেরিয়েবলটি পুনরায় মান নির্ধারণ করতে সহায়তা করে।
উদাহরণ:
(defparameter d 300) ; d ভেরিয়েবলকে 300 দিয়ে ইনিশিয়ালাইজ৩. ভেরিয়েবল মান পরিবর্তন (Variable Value Modification)
LISP-এ ভেরিয়েবলের মান পরিবর্তন করার জন্য setq ব্যবহার করা হয়। ভেরিয়েবলকে নতুন মান দিয়ে সেট করা হয়।
উদাহরণ:
(setq x 50) ; x ভেরিয়েবলের মান 50 হয়ে যাবে
(setq x (+ x 10)) ; x ভেরিয়েবলের মান 60 হবে (50 + 10)৪. স্ট্রিং এবং লিস্ট ইনিশিয়ালাইজেশন
এছাড়া LISP-এ স্ট্রিং এবং লিস্ট ডাটা টাইপগুলোর ইনিশিয়ালাইজেশনও করা যায়।
স্ট্রিং ইনিশিয়ালাইজেশন:
(setq mystring "Hello, LISP!") ; স্ট্রিং ইনিশিয়ালাইজলিস্ট ইনিশিয়ালাইজেশন:
(setq mylist '(1 2 3 4 5)) ; লিস্ট ইনিশিয়ালাইজসারসংক্ষেপ
| ফাংশন | ব্যাখ্যা | উদাহরণ |
|---|---|---|
setq | ভেরিয়েবল ডিক্লেয়ার ও ইনিশিয়ালাইজ করতে ব্যবহৃত। | (setq x 10) |
defvar | প্রথমবার ভেরিয়েবল ডিফাইন করতে ব্যবহৃত (পুনরায় মান নির্ধারণ নয়)। | (defvar y 20) |
defparameter | ভেরিয়েবল ডিফাইন ও ইনিশিয়ালাইজ করতে ব্যবহৃত (পুনরায় মান নির্ধারণ)। | (defparameter z 30) |
LISP-এ ভেরিয়েবল ডিক্লেয়ার এবং ইনিশিয়ালাইজ করার জন্য setq, defvar, এবং defparameter প্রধান ফাংশন হিসেবে ব্যবহৃত হয়। এগুলো দিয়ে আপনি ভেরিয়েবল সৃষ্টি এবং তার প্রথম মান নির্ধারণ করতে পারবেন।
Scoping একটি প্রোগ্রামিং ভাষায় ভেরিয়েবলের মান কোথায় এবং কিভাবে অ্যাক্সেস করা যাবে, তা নির্ধারণ করে। ভেরিয়েবলকে একটি প্রোগ্রাম বা ফাংশনের মধ্যে ব্যবহারের সময়, এটি কোন কোড ব্লকের মধ্যে ব্যবহৃত হতে পারে, তা scoping নির্ধারণ করে।
Dynamic Scoping এবং Lexical Scoping দুইটি ভিন্ন ধরনের স্কোপিং মডেল, যা ভেরিয়েবল রেজোলিউশনের (অর্থাৎ, ভেরিয়েবলের মান খুঁজে বের করার পদ্ধতি) মধ্যে পার্থক্য তৈরি করে। LISP বা অন্যান্য প্রোগ্রামিং ভাষায় এই স্কোপিং ধারণাগুলি ভেরিয়েবল হ্যান্ডলিংয়ে গুরুত্বপূর্ণ ভূমিকা পালন করে।
১. Dynamic Scoping
Dynamic Scoping হল এমন একটি স্কোপিং মডেল যেখানে ভেরিয়েবলের মান কেবলমাত্র প্রোগ্রাম চলাকালীন সময়ে যে ফাংশন কল (function call) সঠিকভাবে চালানো হচ্ছে তার উপর নির্ভর করে। অর্থাৎ, একটি ভেরিয়েবল যেখানে ঘোষণা করা হয়েছে, তা রানটাইমে তার বর্তমান সাপেক্ষে এক্সেস করা হয়। Dynamic scoping তে, যখন একটি ফাংশন কল করা হয়, তখন সেই ফাংশন তার বাইরের ভেরিয়েবলের মান দেখতে পারে, যদি সেই ভেরিয়েবলটি বর্তমানে অ্যাক্সেসযোগ্য হয়।
উদাহরণ (Dynamic Scoping):
(setq x 5) ; গ্লোবাল ভেরিয়েবল x ঘোষণা
(defun foo ()
(print x)) ; foo ফাংশন x এর মান প্রিন্ট করবে
(defun bar ()
(setq x 10) ; x কে 10 করে সেট করা
(foo)) ; foo ফাংশন কল
(bar) ; আউটপুট হবে 10এখানে, x এর মান bar ফাংশনের মধ্যে পরিবর্তিত হওয়ার পর, foo ফাংশন কল করার সময় এটি x এর নতুন মান (10) দেখতে পাচ্ছে, কারণ Dynamic Scoping তে x এর মান রানটাইমে সেট হয়।
বৈশিষ্ট্য:
- Runtime Binding: স্কোপিং যখন রানটাইমে নির্ধারিত হয়।
- চেইনিং: যখন একটি ফাংশন কল করা হয়, তখন এটি তার বাইরের ভেরিয়েবলগুলোর মান অ্যাক্সেস করতে পারে।
- কমন ব্যবহৃত ভাষা: কিছু পুরোনো ভাষা (যেমন, Early versions of LISP) Dynamic Scoping ব্যবহার করত।
২. Lexical Scoping
Lexical Scoping বা Static Scoping হল এমন একটি স্কোপিং মডেল যেখানে ভেরিয়েবলের মান কোড লেখার সময় (compile-time) নির্ধারিত হয়, এবং একটি ফাংশন বা কোড ব্লকের মধ্যে একটি ভেরিয়েবলকে কিভাবে অ্যাক্সেস করা যাবে তা কোডের অবস্থান দ্বারা নির্ধারিত হয়, রানটাইমে না।
Lexical Scoping তে, একটি ফাংশন তার নিজস্ব স্কোপের মধ্যে থাকা ভেরিয়েবলগুলিকে প্রাধান্য দেয়। যদি ভেরিয়েবলটি তার স্কোপে না থাকে, তাহলে এটি বাইরের স্কোপে খোঁজা হয়, এবং এটি যদি বাইরের স্কোপেও না থাকে, তাহলে ত্রুটি ঘটে।
উদাহরণ (Lexical Scoping):
(setq x 5) ; গ্লোবাল ভেরিয়েবল x ঘোষণা
(defun foo ()
(print x)) ; foo ফাংশন x এর মান প্রিন্ট করবে
(defun bar ()
(let ((x 10)) ; x এখানে 10 হবে
(foo))) ; foo ফাংশন কল
(bar) ; আউটপুট হবে 5এখানে, bar ফাংশনের মধ্যে x এর মান ১০ হওয়ার পরও foo ফাংশন যখন x প্রিন্ট করে, তখন এটি গ্লোবাল স্কোপের x (5) এর মান প্রদর্শন করবে। কারণ, Lexical Scoping তে foo ফাংশনটির স্কোপ প্রথমে চেক করা হয় এবং এখানে foo ফাংশন গ্লোবাল স্কোপে x এর মান দেখতে পায়।
বৈশিষ্ট্য:
- Compile-time Binding: ভেরিয়েবলের মান কম্পাইল টাইমে নির্ধারিত হয়।
- স্ট্যাটিক স্কোপ: কোডের ভেতরে কোথায় একটি ভেরিয়েবল ডিফাইন করা হয়েছে, তার উপর নির্ভর করে এটি কোথায় অ্যাক্সেস করা যাবে।
- বেশি ব্যবহৃত ভাষা: অধিকাংশ আধুনিক প্রোগ্রামিং ভাষা (যেমন, Python, Java, JavaScript, এবং LISP এর আধুনিক ডায়ালেক্টগুলি) Lexical Scoping ব্যবহার করে।
Dynamic এবং Lexical Scoping এর মধ্যে পার্থক্য
| বৈশিষ্ট্য | Dynamic Scoping | Lexical Scoping |
|---|---|---|
| ভেরিয়েবল রেজোলিউশন | রানটাইমে নির্ধারিত হয়, যখন ফাংশন কল হয় | কম্পাইল টাইমে নির্ধারিত হয়, কোডের স্থানের উপর ভিত্তি করে |
| প্রোগ্রাম কোডের অবস্থান | রানটাইমে কোডের মধ্যে যেখানে কল হয়, সেখানে অনুসন্ধান হয় | কোডের অবস্থান বা স্কোপে ফাংশন ডিফাইন হওয়ার সময় অনুসন্ধান হয় |
| ফাংশন কলের সময় স্কোপিং | বাইরের স্কোপ থেকে মান পাওয়া যেতে পারে ফাংশন কলের সময় | ফাংশনটি তার নিজের স্কোপের মধ্যে থাকে, বাইরের স্কোপে নয় |
| কমন ব্যবহৃত ভাষা | পুরনো LISP ডায়ালেক্টগুলো, কিছু স্ক্রিপ্টিং ভাষা | অধিকাংশ আধুনিক ভাষা (Python, Java, JavaScript, এবং LISP) |
সারসংক্ষেপ:
- Dynamic Scoping তে ভেরিয়েবলের মান রানটাইমে নির্ধারিত হয় এবং একটি ফাংশন কল করার সময় এটি বাইরের স্কোপের ভেরিয়েবলদের মান দেখতে পারে।
- Lexical Scoping তে, ভেরিয়েবলের মান কম্পাইল টাইমে নির্ধারিত হয় এবং একটি ফাংশন তার নিজের স্কোপের ভেরিয়েবলকেই প্রাধান্য দেয়, বাইরের স্কোপে থাকা ভেরিয়েবলকে নয়।
LISP এর আধুনিক ডায়ালেক্টগুলো সাধারণত Lexical Scoping ব্যবহার করে, যা প্রোগ্রামিংয়ের নির্ভরযোগ্যতা এবং ডিবাগিং সহজ করে তোলে।
Local এবং Global ভেরিয়েবল হল দুটি গুরুত্বপূর্ণ ধারণা, যা প্রোগ্রামিং ভাষায় ভেরিয়েবলের স্কোপ (scope) এবং জীবনকাল (lifetime) নির্ধারণ করে। LISP সহ সকল প্রোগ্রামিং ভাষায় এই দুটি ভেরিয়েবল আলাদা ভূমিকা পালন করে।
এখানে Local এবং Global ভেরিয়েবলের মধ্যে পার্থক্য তুলে ধরা হলো:
১. Global Variables (গ্লোবাল ভেরিয়েবল)
Global Variables হল এমন ভেরিয়েবল, যেগুলি প্রোগ্রামের মধ্যে যে কোনো জায়গায় অ্যাক্সেস করা যেতে পারে, অর্থাৎ এগুলির স্কোপ পুরো প্রোগ্রাম জুড়ে থাকে। আপনি যখন একটি ভেরিয়েবলকে গ্লোবাল হিসেবে ঘোষণা করেন, তখন সেই ভেরিয়েবলটি প্রোগ্রামের যে কোনো ফাংশন বা স্কোপে ব্যবহৃত হতে পারে।
Global Variables এর বৈশিষ্ট্য:
- স্কোপ: গ্লোবাল ভেরিয়েবলটির স্কোপ পুরো প্রোগ্রাম জুড়ে থাকে। অর্থাৎ, একবার এক ভেরিয়েবল গ্লোবাল হলে তা প্রোগ্রামের যেকোনো জায়গা থেকে অ্যাক্সেস করা সম্ভব।
- অ্যাক্সেস: গ্লোবাল ভেরিয়েবল ফাংশনের বাইরেও অ্যাক্সেস করা যায় এবং প্রোগ্রামের যে কোনো অংশে তা পরিবর্তন করা সম্ভব।
- জীবনকাল: গ্লোবাল ভেরিয়েবল প্রোগ্রাম চলাকালীন জীবিত থাকে এবং প্রোগ্রাম বন্ধ না হওয়া পর্যন্ত তার মান সংরক্ষিত থাকে।
Global Variables ব্যবহার উদাহরণ:
(setq x 10) ; গ্লোবাল ভেরিয়েবল x ডিফাইন করা হচ্ছে
(defun display-x ()
(print x)) ; গ্লোবাল x ভেরিয়েবল এক্সেস করা হচ্ছে
(display-x) ; আউটপুট: 10এখানে, x একটি গ্লোবাল ভেরিয়েবল, যা display-x ফাংশন থেকে অ্যাক্সেস করা হয়েছে। যেহেতু এটি গ্লোবাল, তাই x যে কোনো ফাংশন থেকে এক্সেস করা সম্ভব।
২. Local Variables (লোকাল ভেরিয়েবল)
Local Variables হল এমন ভেরিয়েবল, যেগুলি শুধুমাত্র একটি নির্দিষ্ট ফাংশনের মধ্যে সীমাবদ্ধ থাকে। একটি লোকাল ভেরিয়েবল শুধুমাত্র তার সংজ্ঞায়িত ফাংশনের মধ্যে ব্যবহৃত হতে পারে এবং তার বাইরের কোড থেকে এক্সেস করা সম্ভব নয়। লোকাল ভেরিয়েবল শুধুমাত্র ফাংশনের চলমান স্কোপে থাকে এবং ফাংশনটির এক্সিকিউশন শেষ হওয়ার পর তার জীবনকাল শেষ হয়ে যায়।
Local Variables এর বৈশিষ্ট্য:
- স্কোপ: লোকাল ভেরিয়েবলটির স্কোপ শুধুমাত্র সেই ফাংশনের মধ্যে থাকে যেখানে সেটি ডিফাইন করা হয়। আপনি যদি অন্য ফাংশন থেকে এটি অ্যাক্সেস করতে চান, তবে তা সম্ভব হবে না।
- অ্যাক্সেস: লোকাল ভেরিয়েবল শুধুমাত্র তার ডিফাইন করা ফাংশনের মধ্যে অ্যাক্সেসযোগ্য।
- জীবনকাল: লোকাল ভেরিয়েবলটি ফাংশনের জীবনকাল অনুসারে জীবিত থাকে। ফাংশনটি শেষ হয়ে গেলে, লোকাল ভেরিয়েবলটির মান মুছে যায় এবং তা আর অ্যাক্সেসযোগ্য থাকে না।
Local Variables ব্যবহার উদাহরণ:
(defun calculate-sum (a b)
(setq sum (+ a b)) ; sum একটি লোকাল ভেরিয়েবল
(print sum))
(calculate-sum 3 5) ; আউটপুট: 8এখানে, sum একটি লোকাল ভেরিয়েবল, যা calculate-sum ফাংশনের মধ্যে ডিফাইন করা হয়েছে। এটি ফাংশনের বাইরে এক্সেস করা যাবে না এবং শুধুমাত্র এই ফাংশনেই ব্যবহৃত হতে পারে।
৩. Local এবং Global Variables এর মধ্যে পার্থক্য
| বৈশিষ্ট্য | Local Variables | Global Variables |
|---|---|---|
| স্কোপ | লোকাল ভেরিয়েবল শুধুমাত্র তার ডিফাইন করা ফাংশনের মধ্যে থাকে। | গ্লোবাল ভেরিয়েবল পুরো প্রোগ্রাম জুড়ে অ্যাক্সেসযোগ্য। |
| অ্যাক্সেস | লোকাল ভেরিয়েবল ফাংশনের বাইরে অ্যাক্সেস করা সম্ভব নয়। | গ্লোবাল ভেরিয়েবল যেকোনো ফাংশন বা কোড থেকে অ্যাক্সেস করা যায়। |
| জীবনকাল | ফাংশন এক্সিকিউট হওয়ার সময়ই এটি থাকে, তারপর মুছে যায়। | প্রোগ্রাম চলাকালীন সময়ের মধ্যে এটি জীবিত থাকে। |
| মান পরিবর্তন | লোকাল ভেরিয়েবল শুধুমাত্র তার ফাংশনে পরিবর্তন করা যায়। | গ্লোবাল ভেরিয়েবল প্রোগ্রামের যে কোনো জায়গায় পরিবর্তন করা যায়। |
| প্রভাব | শুধু সংশ্লিষ্ট ফাংশনের উপর প্রভাব ফেলে। | পুরো প্রোগ্রাম বা যেকোনো ফাংশনে প্রভাব ফেলে। |
৪. কখন কোনটি ব্যবহার করবেন?
- Local Variables ব্যবহার করুন যখন আপনি এমন ভেরিয়েবল চাচ্ছেন যার মান শুধুমাত্র একটি নির্দিষ্ট ফাংশনের মধ্যে প্রয়োজন। এটি কোডকে আরও পরিষ্কার এবং নিরাপদ করে, কারণ আপনি জানেন যে ওই ফাংশনের বাইরে ভেরিয়েবলটি পরিবর্তন হবে না।
- Global Variables ব্যবহার করুন যখন আপনি এমন ভেরিয়েবল চান যা প্রোগ্রামের একাধিক অংশে ব্যবহৃত হবে। তবে, গ্লোবাল ভেরিয়েবল ব্যবহারের ক্ষেত্রে সতর্ক থাকতে হবে, কারণ এটি প্রোগ্রামের অন্যান্য অংশে অনাকাঙ্ক্ষিত পরিবর্তন ঘটাতে পারে।
সারসংক্ষেপ
Local এবং Global Variables LISP প্রোগ্রামিং ভাষার গুরুত্বপূর্ণ দুটি ধারণা। Local Variables শুধুমাত্র তাদের ডিফাইন করা ফাংশনের মধ্যে ব্যবহৃত হয় এবং তার বাইরের অংশে এক্সেস করা যায় না, যেখানে Global Variables পুরো প্রোগ্রাম জুড়ে অ্যাক্সেসযোগ্য থাকে। দুটি ভেরিয়েবল ব্যবহারের উপযুক্ত জায়গা চয়ন করলে প্রোগ্রাম আরও কার্যকরী এবং সচল হবে।
LISP প্রোগ্রামিং ভাষায় let, setq, এবং defvar হল তিনটি গুরুত্বপূর্ণ কনস্ট্রাক্ট যা ভেরিয়েবল ডিফাইন এবং অ্যাসাইন করার জন্য ব্যবহৃত হয়। এই তিনটি কনস্ট্রাক্টের মধ্যে কিছু পার্থক্য আছে এবং প্রতিটির নির্দিষ্ট ব্যবহারের উদ্দেশ্য রয়েছে। এখানে আমরা তাদের ব্যবহার এবং পার্থক্য বিস্তারিতভাবে আলোচনা করব।
১. let (স্থানীয় ভেরিয়েবল ডিফাইন করা)
let একটি ব্লক-বদ্ধ স্থানীয় ভেরিয়েবল ডিফাইন করার জন্য ব্যবহৃত হয়। এটি একটি স্থানীয় স্কোপ তৈরি করে, যেখানে আপনি ভেরিয়েবল ডিফাইন করেন এবং সেই ভেরিয়েবলগুলি কেবল সেই ব্লক বা স্কোপের মধ্যে বৈধ থাকে। যখন স্কোপ শেষ হয়, তখন ঐ ভেরিয়েবলগুলি অদৃশ্য হয়ে যায়। এটি সাধারণত একটি ফাংশন বা কার্যকলাপের মধ্যে ব্যবহৃত হয়।
ব্যবহারের ধরন:
(let ((var1 value1)
(var2 value2))
;; এখানে var1 এবং var2 শুধুমাত্র let ব্লকের মধ্যে অ্যাক্সেসযোগ্য
(print var1)
(print var2))উদাহরণ:
(let ((x 5) (y 10))
(+ x y)) ; আউটপুট: 15এখানে:
xএবংyহল স্থানীয় ভেরিয়েবল।- এই ভেরিয়েবলগুলো শুধুমাত্র
letব্লকের মধ্যে কার্যকর, এবং তার পর তাদের মান আর ব্যবহার করা যাবে না।
২. setq (ভেরিয়েবল অ্যাসাইন করা)
setq একটি গ্লোবাল ভেরিয়েবল এর মান অ্যাসাইন করতে ব্যবহৃত হয়। এটি ভেরিয়েবল এর মান পরিবর্তন করে, এবং সেই ভেরিয়েবলটি গ্লোবাল স্কোপে পাওয়া যায়। setq এর মধ্যে প্রথম আর্গুমেন্ট হচ্ছে ভেরিয়েবলের নাম এবং দ্বিতীয় আর্গুমেন্ট হচ্ছে তার নতুন মান।
ব্যবহারের ধরন:
(setq var value)উদাহরণ:
(setq x 5)
(setq y (+ x 10)) ; y এর মান হবে 15এখানে:
setqভেরিয়েবলের মানকে গ্লোবাল স্কোপে পরিবর্তন করে। অর্থাৎ, এখানেxএবংyগ্লোবাল ভেরিয়েবল।
৩. defvar (গ্লোবাল ভেরিয়েবল ডিফাইন করা)
defvar ব্যবহার করা হয় গ্লোবাল ভেরিয়েবল ডিফাইন করতে এবং যদি সেই ভেরিয়েবল আগে থেকেই ডিফাইন না থাকে তবে সেটির মান অ্যাসাইন করতে। যদি ভেরিয়েবলটি আগে থেকে ডিফাইন করা থাকে, তাহলে তার মান পরিবর্তন হবে না। এটি সাধারণত গ্লোবাল ভেরিয়েবল তৈরি করার জন্য ব্যবহার করা হয়।
ব্যবহারের ধরন:
(defvar varname initial-value)উদাহরণ:
(defvar x 10)
(defvar y (+ x 5)) ; y এর মান হবে 15এখানে:
defvarব্যবহার করলে যদিxএবংyআগে থেকেই ডিফাইন করা না থাকে, তবে তাদের মান ডিফাইন হবে। তবে যদি তারা আগে থেকেই ডিফাইন হয়ে থাকে, তবে তাদের মান অপরিবর্তিত থাকবে।
পার্থক্য
| কনস্ট্রাক্ট | ব্যবহার | বৈশিষ্ট্য |
|---|---|---|
let | স্থানীয় ভেরিয়েবল ডিফাইন করে, যেগুলি শুধু let ব্লকের মধ্যে বৈধ থাকে। | ভেরিয়েবলগুলি শুধুমাত্র ব্লকের মধ্যে বৈধ থাকে। |
setq | গ্লোবাল ভেরিয়েবলের মান পরিবর্তন করে। | গ্লোবাল ভেরিয়েবল হিসাবে ব্যবহার হয়। |
defvar | গ্লোবাল ভেরিয়েবল ডিফাইন করে এবং যদি পূর্বে ডিফাইন করা না থাকে তবে মান অ্যাসাইন করে। | পূর্বে ডিফাইন করা ভেরিয়েবলের মান পরিবর্তন হয় না। |
উদাহরণ
let উদাহরণ:
(let ((a 3) (b 4))
(print (+ a b))) ; আউটপুট: 7এখানে a এবং b শুধুমাত্র let ব্লকের মধ্যে বৈধ, তাদের স্কোপ বাইরে পৌঁছাবে না।
setq উদাহরণ:
(setq a 5)
(setq b 10)
(print (+ a b)) ; আউটপুট: 15এখানে a এবং b গ্লোবাল ভেরিয়েবল হিসেবে অ্যাসাইন করা হয়েছে এবং তাদের মান পরিবর্তন করা হয়েছে।
defvar উদাহরণ:
(defvar a 5)
(defvar b 10)
(print (+ a b)) ; আউটপুট: 15এখানে a এবং b ডিফাইন করা হয়েছে এবং যদি তারা আগে থেকে ডিফাইন না হয়ে থাকে, তবে তাদের মান ৫ এবং ১০ হবে।
সারসংক্ষেপ
letব্যবহার করে আপনি স্থানীয় ভেরিয়েবল তৈরি করতে পারেন যেগুলি কেবলমাত্র একটি ব্লকের মধ্যে বৈধ থাকে।setqব্যবহার করে আপনি গ্লোবাল ভেরিয়েবলের মান পরিবর্তন করতে পারেন।defvarব্যবহার করে আপনি গ্লোবাল ভেরিয়েবল ডিফাইন করতে পারেন, তবে যদি সেই ভেরিয়েবলটি আগে থেকেই ডিফাইন করা থাকে তবে তার মান পরিবর্তিত হবে না।
এগুলো LISP ভাষায় ভেরিয়েবল ব্যবস্থাপনার মৌলিক উপাদান।
Read more