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 ব্যবহার করে, যা প্রোগ্রামিংয়ের নির্ভরযোগ্যতা এবং ডিবাগিং সহজ করে তোলে।
Read more