# উচ্চস্তরের প্রোগ্রামিং ভাষা

পাইথন একটি উচ্চস্তরের প্রোগ্রামিং ভাষা
**উচ্চস্তরের প্রোগ্রামিং ভাষা** (ইংরেজি: High-level programming language) হল এমন একটি প্রোগ্রামিং ভাষা যা অন্যান্য নিম্নস্তরের প্রোগ্রামিং ভাষাগুলোর তুলনায় আরও বিমূর্ত (abstract), সহজে ব্যবহারযোগ্য ও বিভিন্ন প্ল্যাটফর্মের মধ্যে সহজে বহনযোগ্য (portable)। এ ধরনের ভাষায় ব্যবহারকারীদের কম্পিউটার মেমরি নিয়ে সরাসরি কাজ করতে দেয়া হয়না।

## উচ্চস্তরের ভাষার বৈশিষ্ট্য

• হাইলেভেল বা উচ্চস্তরের ভাষায় লিখিত প্রােগ্রাম যেকোনাে কম্পিউটারে ব্যবহার করা যায়।

• মানুষের পক্ষে লাে লেভেলের চেয়ে হাইলেভেল ভাষা শেখা সহজ।

• হাইলেভেল ভাষায় তাড়াতাড়ি প্রােগ্রাম লেখা যায়।

• লাে লেভেল ভাষার চার বা পাঁচটি নির্দেশের জায়গায় হাইলেভেল ভাষার মাত্র একটি বাক্য লিখলেই চলে।

• প্রােগ্রাম লেখার জন্য কম্পিউটার সম্পর্কে ধারণার প্রয়ােজন নেই।

• হাইলেভেল ভাষায় লেখা প্রােগ্রামের ভুল সংশােধন করা তুলনামূলক সহজ।

• অসংখ্য লাইব্রেরি ফাংশন হাইলেভেল প্রােগ্রামে বিদ্যমান থাকে।

• প্রোগ্রাম তৈরির সময় হার্ডওয়্যার নিয়ে ভাবতে হয় না।

• কাজের পরিধি বড় বিধায় প্রোগ্রাম তুলনামূলকভাবে ছোট হয়।

## উচ্চস্তরের ভাষার অসুবিধা

• প্রোগ্রাম লেখার সময় আগে এ ভাষার স্ট্রাকচার জানতে হয়।

• প্রোগ্রাম তৈরিতে ব্যবহৃত উচ্চস্তরের ভাষার প্রতিটি কমান্ডের সিনটেক্স জানতে হয়।

• এ ভাষাকে মেশিন ভাষাতে রূপান্তরের জন্য কম্পাইলার প্রয়োজন হয় যা অনেকটা ব্যয়বহুল।

## চলমান প্রোগ্রামিং ভাষা

কম্পিউটার বিজ্ঞানের পরিভাষায় **চলমান প্রোগ্রামিং ভাষা** (ইংরেজি: Dynamic programming language) বলতে এক শ্রেণীর উচ্চস্তরের প্রোগ্রামিং ভাষাকে বোঝায়। অন্যান্য অনেক প্রোগ্রামিং ভাষা যে কাজ গুলি কম্পাইলকরণ ধাপে নিষ্পন্ন করে, চলমান প্রোগ্রামিং ভাষাগুলিতে সেই কাজগুলি প্রোগ্রাম "রান" করার সময়, "চলমান" অবস্থায় নিষ্পন্ন করা হয়। এদের মধ্যে আছে প্রোগ্রামে নতুন কোড যোগ করা, প্রোগ্রামের ডেফেনিশন ও অবজেক্টগুলি সম্প্রসারণ করা, টাইপ ব্যবস্থা পরিবর্তন করা, ইত্যাদি এবং এগুলি সবই প্রোগ্রাম নির্বাহ বা "রান" করার সময় সংঘটিত হয়।

চলমান ভাষা হলেই যে তার টাইপ ব্যবস্থা চলমান হবে এরকম নিশ্চয়তা নেই। তবে বেশির ভাগ চলমান প্রোগ্রামিং ভাষায় চলমান টাইপকৃত (dynamically typed)।

## উদাহরণ

জাভাস্ক্রিপ্ট, পাইথন, রুবি, পিএইচপি, লুয়া, পার্ল ইত্যাদি জনপ্রিয় চলমান প্রোগ্রামিং ভাষা। নিম্নলিখিত প্রোগ্রামিং ভাষাগুলো সাধারণত চলমান প্রোগ্রামিং ভাষা বলে মনে করা হয়:

* ActionScript
* BeanShell
* সি শার্প (using Reflection)
* Clojure
* Cobolscript
* ColdFusion Markup Language
* Common Lisp and most other লিস্প
* Dylan
* E
* Elixir
* Erlang
* Gambas
* GDScript
* Groovy
* জাভা (using Reflection)
* জাভাস্ক্রিপ্ট
* Julia
* লুয়া
* ম্যাটল্যাব/Octave
* অবজেক্টিভ সি
* পার্ল
* পিএইচপি
* PowerShell
* Prolog
* Python
* R
* Rebol
* রুবি
* Smalltalk
* SuperCollider
* Tcl
* VBScript
* Wolfram Language

## লো এবং হাই লেভেল প্রোগ্রামিং ভাষায় এর ব্যবহারঃ

প্রোগ্রামিং ভাষার উপর ভিত্তি করে কোডের স্ব-পরিবর্তন বিভিন্নভাবে হতে পারে। এটি পয়েন্টারে পরিবর্তনশীল কম্পাইলার বা ইন্টারপ্রেটার ইঞ্জিনের সাহায্যেও হতে পারেঃ

* **পূর্ববর্তী নির্দেশনাবলী পরিবির্তিত করে** ( অথবা নির্দেশনাবলী একটি অংশ যেমন অপকোড, রেজিস্টার, ফ্ল্যাগ বা অ্যাড্রেস) অথবা
* **সরাসরি সম্পূর্ণ নির্দেশাবলী তৈরি করে** অথবা মেমরিতে থাকা ক্রমানুযায়ী নির্দেশাবলী
* **সোর্স কোড তৈরি অথবা পরিমার্জন করে** একটি 'মিনি কম্পাইলার' অথবা পরিবর্তনশীল ইন্টারপ্রেটার ব্যবহার করে
* **একটি সম্পূর্ণ পরিবর্তনশীল প্রোগ্রাম তৈরি করা** এবং তারপর সেটি এক্সিকিউট করা

### অ্যাসেম্বলি ভাষা

অ্যাসেম্বলি ভাষা ব্যবহার করে স্ব-পরিবর্তনশীল কোড বাস্তবায়ন করা মোটামুটি সহজ। এক্ষেত্রে নির্দেশনাগুলো মেমরিতে নতুন করে তৈরি করা যায় এবং এগুলো পরিবর্তনশীল। অথবা পূর্বের অসুরক্ষিত কোড মুছে ফেলেও আগের মেমরিতেই নতুন করে কোড করা যায়। উভয়ক্ষেত্রেই এমনভাবে কোড লিখতে হয়, যেন একটি সাধারণ কম্পাইলার সহজেই কোডটিকে অবজেক্ট কোড হিসাবে তৈরি করতে পারে। এক্ষেত্রে আধুনিক প্রসেসর ব্যবহার করা হলে, সেখানে সিপিইউ ক্যাশে কিছু অনিচ্ছাকৃত পার্শ্ব প্রতিক্রিয়া হতে পারে। এই পদ্ধতিটি অ্যাসেম্বলি ভাষায় লিখা কোডের প্রথম শর্তটি পরীক্ষা করার জন্য বেশি ব্যবহার করা হয়। এর একটি উৎকৃষ্ট উদাহরণ হচ্ছে আইবিএম/৩৬০ এর অ্যাসেম্বলি ভাষা। অ্যাসেম্বলি ভাষায় স্ব-পরিবর্তনশীল কোড ব্যবহার করলে নির্দেশনাবলী পরিমাণ (N x 1)-1 সংখ্যক কমে। এখানে N হচ্ছে ফাইলে রেকর্ডের সংখ্যা। (পূর্বের অসুরক্ষিত কোড মুছে ফেলে নতুন কোড লিখার কারণে -1 ব্যবহার করা হয়েছে)।

```
SUBRTN NOP OPENED      FIRST TIME HERE?
* The NOP is x'4700'<Address_of_opened>
       OI    SUBRTN+1,X'F0'  YES, CHANGE NOP TO UNCONDITIONAL BRANCH (47F0...)
       OPEN   INPUT               AND  OPEN THE INPUT FILE SINCE IT'S THE FIRST TIME THRU
OPENED GET    INPUT        NORMAL PROCESSING RESUMES HERE
      ...
```

বিকল্প কোডটিকে প্রতিবারই একটি 'ফ্ল্যাগ' পরীক্ষার মাধ্যমে যেতে হয়। এই নিঃশর্ত শাখাটি পূর্বের কোডের চেয়ে সামান্য দ্রুত এবং সেইসাথে সামগ্রিকভাবে কোডের দৈর্ঘ্যও হ্রাস করে। পরবর্তীতে অপারেটিং সিস্টেমগুলোতে প্রোগ্রামগুলো সুরক্ষিত মেমরিতে রাখার ফলে এই পদ্ধতি আর ব্যবহার করা হত না। এর বদলে পয়েন্টারটিকে সাবরুটিনে পরিবর্তন করে দেয়া হত। এক্ষেত্রে পয়েন্টারটি পরিবর্তনশীল মেমরিতে রাখা যেতে পারে। এখানে কোডের শাখার বদলে পয়েন্টারটি লোড করতে হয় এবং সাবরুটিনে যুক্ত করতে হয়। এতে করে প্রোগ্রামের কোডে নির্দেশনার পরিমাণ বাড়ে। কিন্তু যেহেতু এখানে নিঃশর্ত শাখাগুলোর কোন দরকার হয়না, সেহেতু তুলনামুলকভাবে সম্পূর্ণ প্রোগ্রামের লাইন সংখ্যা কমে।

### হাই লেভেল প্রোগ্রামিং ভাষা

কিছু প্রোগ্রামিং ভাষায় স্পষ্টভাবে স্ব-পরিবর্তনকারী কোড
সমর্থন করে। উদাহরণস্বরূপ, ব্যবসায়িক কাজে ব্যবহৃত এক বিশেষ ধরনের কম্পিউটার ভাষা, কোবোলে কোড এক্সিকিউট হওয়ার সময় স্ব-পরিবর্তনকারী কোড কাজ করতে পারে। এক-ব্যাচ প্রোগ্রামিং ভাষায় স্ব-পরিবর্তনকারী কোড ব্যবহার করতে হয়। এছাড়াও 'ক্লিপার' এবং 'এসপিআইটিবিওএল' প্রোগ্রামিং ভাষাগুলোও সরাসরি স্ব-পরিবর্তনকারী কোডের সুবিধা প্রদান করে। বি৬৭০০ সিস্টেমে ব্যবহৃত অ্যালগল কম্পাইলার কোড এক্সিকিউট হওয়ার সময় টেক্সট স্ট্রিং চালনা করতে পারে এবং পরে আবার সেটিকে প্রয়োজন হলে পুনরায় ডেকে ব্যবহারও করতে পারে।

কিছু কিছু প্রোগ্রামিং ভাষায় মেশিন কোডই হচ্ছে সোর্স কোড এবং এই কোড সবসময়ই পরিবর্তন করা যায়। স্নোবল প্রোগ্রামিং ভাষায় সোর্স কোড একটি টেক্সট অ্যারে এর উপাদান হিসিবে এক্সিকিউট হয়। অন্যান্য প্রোগ্রামিং ভাষা যেমন পার্ল এবং পাইথনে প্রোগ্রামগুলো রান-টাইমে 'ইভাল' ফাংশন ব্যবহার করে নতুন কোড তৈরি করতে পারে, কিন্তু পূর্বের কোডে কোনরূপ পরিবর্তন করতে পারে না। এই পরিবর্তন বিষয়ক বিভ্রমটি (এমনকি মেশিন কোডও মূলত বদলানো হয়না) ফাংশন পয়েন্টারে পরিবর্তন করার কারণে ঘটে থাকে। নিচের জাভাস্ক্রিপ্টের উদাহরণটি লক্ষ্য করা যাকঃ

```
 var f = function (x) {return x + 1};

 // assign a new definition to f:
 f = new Function('x', 'return x + 2');

```
'লিস্প ম্যাক্রোস' এর সাহায্যে একটি প্রোগ্রামে থাকা স্ট্রিং এর কোনরূপ শব্দবিশ্লেষণ ছাড়াই রানটাইমে কোড পরিবর্তন করার সুযোগ পায়।

প্যুশ প্রোগ্রামিং ভাষা এমন একটি প্রোগ্রামিং ভাষা, যেটি সহজে স্ব-পরিবর্তনকারী কোড ব্যবহার করার জন্য তৈরি করা হয়েছে। এটি কোন উচ্চ স্তরের প্রোগ্রামিং ভাষা নয়, কিন্তু অ্যাসেম্বলি ভাষার মত নিন্ম স্তরেরও নয়।

#### চক্রবৃদ্ধি পরিবর্তন

একাধিক উইন্ডোজ সিস্টেম আসার আগে, কমান্ড-লাইন সিস্টেমে একটি মেন্যু সিস্টেম থাকতো, যার সাহায্যে রানিং কমান্ডের কোড পরিবর্তন করার সুযোগ ছিল। মনে করুন, একটি ডিওএস স্ক্রিপ্ট ফাইল Menu.bat তে নিচের কোডগুলো থাকতে পারেঃ

```
   :StartAfresh                <-A line *starting* with a colon marks a label.
   ShowMenu.exe
```

Menu.bat অপারেশনটি কমান্ড-লাইন থেকে চালানোর পর কোডে থাকা ShowMenu লাইনটি কম্পিউটারের স্ক্রিনে একটি মেন্যু নিয়ে আসে, যেখানে ব্যবহারকারীকে সাহায্য করার জন্য প্রয়োজনীয় তথ্য, উদাহরণ এবং অন্যান্য তথ্য থাকে। এমনকি ব্যবহারকারী এমন কোডও নির্বাচন করতে পারেন, যেখানে *somename* নামক কমান্ড চালনা করলে ShowMenu কমান্ডটি কাজ করবে। ShowMenu কোডটি যখন Menu.bat ফাইলে নিচের মত করে পুনরায় লিখা হবে, তখন ShowMenu কোডটির কাজ শেষ হয়ে যাবে

```
   :StartAfresh
   ShowMenu.exe
   CALL C:\Commands\*somename*.bat
   GOTO StartAfresh
```

কারণ, ডিওএস কমান্ড ইন্টারপ্রেটার এক্সিকিউট করার আগে কোন স্ক্রিপ্ট ফাইল কম্পাইল করেনা। এমনকি এক্সিকিউট করার আগে সম্পূর্ণ প্রোগ্রামটি মেমরিতেও রাখেনা কিংবা পূর্বে রেকর্ড করে রাখা কোন প্রোগ্রামও দেখে না। যখন ShowMenu কাজ শেষ করে, তখন কমান্ড ইন্টারপ্রেটার এক্সিকিউট করার জন্য নতুন একটি কমান্ড পায়। নতুন কমান্ডটি স্ক্রিপ্ট ডিরেক্টরিতে *somename* নামে ছিল। যখন এই কমান্ডটি কাজ শেষ করে, তখন ইন্টারপ্রেটার আবার স্ক্রিপ্ট ফাইলের শুরুতে চলে যায় এবং পুনরায় ShowMenu  অপশনটি পরবর্তী কাজের জন্য তৈরি হয়। এখন স্ক্রিনে আসা মেন্যুটি চলে যাবে এবং ফাইলটি তার পূর্বাবস্থায় ফিরে যাবে। যদিও ফাইলটি তার পূর্বাবস্থায় ফিরে যাওয়াতে কোন কাজ হবেনা, কিন্তু ডিওএস কমান্ড ইন্টারপ্রেটার যেহেতু বাইট পজিশন দ্বারা পরবর্তী কমান্ডের কাজ শুরু করে, সেহেতু ফাইলটি শ্রেণীবন্ধভাবে বিন্যস্ত হয়ে থাকা লাগে। এর ফলে সহজেই ইন্টারপ্রেটারটি পরবর্তী কমান্ডের কাজ শুরু করতে পারবে।

যখন অন্য কমান্ডগুলো কাজ শুরু করে, তখন ShowMenu.exe সিস্টেমটি মেমরিতে থাকেনা। এতে অনেক মেমরি বেঁচে যায়। অর্থাৎ, বলা যায় একটি মেন্যু সিস্টেম(এবং সাথে আরও সম্ভাব্য সাহায্যকারী ফিচার) থাকার সুবিধার পাশাপাশি, যদি ব্যবহারকারীর মেমরির সাইজ কম থাকে, তাহলে এই পদ্ধতিটি অনেক উপকারীও বটে।

### কন্ট্রোল টেবিল

কন্ট্রোল টেবিল ইন্টারপ্রেটার বলতে বুঝায় যেটি নিজে নিজে টেবিল থেকে তথ্য নিয়ে কাজ করতে পারে। (বরং বিশেষভাবে বলা যায়, শর্তযুক্ত নির্দেশ যেমন "IF inputx = 'yyy'" এর মত নয়)।

## ইতিহাস

১৯৪৮ সালের জানুয়ারীতে প্রকাশিত হওয়া আইবিএম এসএসইসি কম্পিউটারটির নিজে নিজে এর নির্দেশনাবলী নিয়ে কাজ করতে সমর্থ্য ছিল। এছাড়া এটি এর নির্দেশনাবলীকে তথ্য হিসেবেও ব্যবহার করতে পারতো। যাইহোক, এই সামর্থ্যটি বাস্তবে খুব কমই ব্যবহার করা হয়েছিল। স্ব-পরিবর্তনকারী কোড আবিষ্কার হওয়ার প্রথম দিকে এটি প্রায়ই কম মেমরির ব্যবহার এবং কোড যাতে দ্রুত কাজ করে সেই উদ্দেশ্যে কিংবা উভয় উদ্দেশ্যে ব্যবহার করা হত। এছাড়াও সাবরুটিন নিয়ে কাজ করতে এবং যখন নির্দেশনাবলীতে কোডের কোন সাধারণ শাখা বা বাদ দেয়ার মত কোন কোড থাকতো, তখনও স্ব-পরিবর্তনকারী কোড ব্যাপকভাবে ব্যবহার করা হত। এই ব্যবহারটি এখনও অন্তত তত্ত্বগতভাবে হলেও আলট্রা-আরআইএসসি আর্কিটেকচারে ব্যবহৃত হচ্ছে। ডোনাল্ড কানুথের এমআইএক্স কম্পিউটারেও সাবরুটিন নিয়ে কাজ করার জন্য স্ব-পরিবর্তনকারী কোড

## ব্যবহার

স্ব-পরিবর্তনকারী কোড বিভিন্ন উদ্দেশ্যে ব্যবহার করা যেতে পারে। যেমনঃ

* একটি অনির্ভরশীল লুপকে আধা-স্বয়ংক্রিয় করা যায়।
* রানটাইম অথবা লোডটাইমে কোড পরিবর্তন বা পরিমার্জন করা যায়। এই সুবিধাটির জন্যই স্ব-পরিবর্তনকারী কোড সবচেয়ে বেশি জনপ্রিয়।
* অবজেক্টের ইনলাইন স্টেট পরিবর্তন করা অথবা ক্লোজারের উচ্চ স্তরের কাজ সহজে করা যায়।
* সাবরুটিনের অ্যাড্রেস একত্র করার জন্য ব্যবহার করা হয়। মূলত একটি কোডের লাইব্রেরি ফাংশন যখন কাজ করে কিংবা কাজ করা শুরু করে, তখন এটি কাজ করে। অথবা এটি প্রত্যেকবার সাবরুটিনের অভ্যন্তরীণ রেফারেন্সগুলোকে একত্র করে যাতে করে তাদের আসল অ্যাড্রেস ব্যবহার করা যায়। (উদাহরণস্বরূপ পরোক্ষ 'স্ব-পরিমার্জন')।
* কম্পিউটিং সিস্টেমের বিবর্তন। যেমন জেনেটিক প্রোগ্রামিং।
* ডিবাগার অথবা ডিঅ্যাসেম্বলার ব্যবহার করে ডিবাগিং এর সাহায্যে লুকানো কোড বের করতে ব্যবহৃত হয়। এছাড়াও বিভিন্ন সফটওয়ারের ভাইরাস বা স্পাইওয়ার খুঁজে বের করার জন্য স্ব-পরিবর্তনকারী কোড ব্যবহার করা হয়।
* কিছু কিছু আর্কিটেকচারে ১০০% মেমোরি ব্যবহারের নিশ্চয়তা দেয়। এটি সাধারণত একটি ঘূর্ণায়মান প্যাটার্নের সাহায্যে অপকোডের পুনরাবৃত্তি অথবা সকল প্রোগ্রাম বা তথ্য মুছে ফেলা কিংবা হার্ডওয়ারের সাহায্যে করা হয়ে থাকে।
* যখন মেমরি বা ডিস্কে জায়গা কম থাকে, তখন কোডকে সংকুচিত করে রানটাইমে কোড এক্সিকিউট করার জন্য ব্যবহৃত হয়।
* কিছু কিছু ফাংশন আছে, যেগুলো স্ব-পরিবর্তনকারী কোড ব্যতীত কিছুতেই কাজ করেনা। উদাহরণস্বরূপ, একটি 'এক নির্দেশ সেট কম্পিউটার (ওআইএসসি)' যেটি কেবল বিয়োগ,এবং,শাখা,যদি অ ঋণাত্মক নির্দেশনাবলী নিয়ে কাজ করে, তারা সেখানে স্ব-পরিবর্তনকারী কোড ব্যবহার করা ছাড়া কিছুতেই করা যাবে না। উদাহরণস্বরূপ,সি প্রোগ্রামিং ভাষায় "\*a = \*\*b" এর সমতুল্য।
* কোডের ভুল ঠিক করার জন্য নির্দেশনাবলীর পরিবর্তনকারী হিসেবে ব্যবহৃত হয়।

### স্টেট-নির্ভরশীল লুপ অপ্টিমাইজ

স্টেট-নির্ভরশীল লুপ অপ্টিমাইজের একটি জেনারেল ফর্ম নিচে দেয়া হল:

```
repeat N times {
   if STATE is 1
      increase A by one
   else
      decrease A by one
   do something with A
}
```

এইক্ষেত্রে স্ব-পরিবর্তনকারী কোড করার জন্য নিচের মত করে লুপটিকে একটু পরিবর্তন করে লিখলেই সমস্যাটির সমাধান হয়ে যায় :

```
 repeat N times {
    *increase* A by one
    do something with A
    when STATE has to switch {
       replace the opcode "increase" above with the opcode to decrease, or vice versa
    }
 }
```

এখানে উল্লেখ্য যে, উপরের কোডে অপকোডের প্রতিস্থাপনটি এভাবে সহজে লিখা যায়, 'এক্সওআর ভ্যারিয়েবল অ্যাড্রেস হবে "অপকোড অফ(আইএনসি) এক্সওআর অপকোড অফ(ডেসিমাল)"'।

এই সমাধানটি ব্যবহার করা হবে কিনা সেটি 'এন' এর মান এবং ফ্রিকুয়েন্সির পরিবর্তনের উপর নির্ভর করে।

### বিশেষীকরণ

মনে করুন, পরিসংখ্যানের একটি সেট অনেক বেশি তথ্য উপাত্ত দিয়ে হিসাব করা হবে। যেখানে গড়, এক্সট্রিমা, এক্সট্রিমার অবস্থান, স্ট্যানডার্ড ডেভিয়েশন ইত্যাদি থাকবে। সাধারণ অবস্থায় সেখানে ডেটা এবং ওয়েট যুক্ত করার অপশন থাকবে। সুতরাং প্রতিটি  xi, wi এর সাথে যুক্ত হবে এবং প্রতিটি ইনডেক্সে ওয়েট থাকলে সেখানে হিসাবটি দুটি নিয়মে হতে পারে। একটি নিয়ম হচ্ছে ওয়েট ব্যবহার করে এবং অপরটি হচ্ছে ওয়েট ব্যবহার ছাড়া।
এখন আরও একটি নিয়ম বিবেচনা করা যাক, ইনডেক্সের প্রতিটি মানই একটি সম্ভাব্য বুলিয়ান মানের সাথে যুক্ত আছে যাতে করে সেটা নিশ্চিত করা যায় যে, মানটি নিয়ে কাজ করা হবে নাকি হবে না। এই কোডটি চারটি ব্যাচে নিয়ন্ত্রণ করা যায়, এর একটি হচ্ছে উৎপাদক দ্বারা কোডটির ফলাফল বের করা এবং এই পদ্ধতিতে কোডের আকার বৃদ্ধি পাবে। অথবা, আরও একটি উপায় হল যে অ্যারেগুলো এড়িয়ে যাওয়া হয়েছিল সেগুলো এবং তাদের ওয়েট একত্রে যুক্ত করে একটি সাময়িক অ্যারেতে রাখা। এখানেও কোড কাজ করার সময় কোডের আকার বৃদ্ধি পাবে। যাইহোক, এভাবে কোড সামান্য পরিবর্তন করে পরিসংখ্যানের হিসাব করা হলে সেখানে অপ্রয়োজনীয় মানগুলো আর থাকবে না এবং কোডও সম্পূর্ণ সঠিক হবে। এখানে কোন মান দ্বিতীয়বার যাচাই করা হবে না এবং ডেটা অ্যারে কেবলমাত্র একবারই চেক করা হবে।

### ছদ্মবেশ হিসাবে ব্যবহার

১৯৮০ সালে অ্যাপল ২ এবং আইবিএম পিসিতে ডিস্কের উপর ভিত্তি করে বানানো প্রোগ্রামগুলোতে কোড যাতে কেউ নকল করতে না পারে, সেজন্য স্ব-পরিবর্তনকারী কোড ব্যবহার করা হত। উদাহরণস্বরূপ, একটি আইবিএম পিসিতে থাকা ফ্লপি ডিস্কে 'int 0x13' নামক কোড থাকতো যেটি প্রোগ্রামের তালিকায় দেখাতো না। কিন্তু এই কোডটি মেমরিতে থাকতো এবং স্বনিয়ন্ত্রিত ভাবে এই প্রোগ্রামটি কাজ করা শুরু করত।

কিছু কিছু প্রোগ্রাম, যেখানে প্রোগ্রামার কোডের উপস্থিতি লুকিয়ে রাখতে চাইতো, সেখানে স্ব-পরিবর্তনকারী কোড ব্যবহার করা হত। যেমন কম্পিউটার ভাইরাস এবং কিছু হ্যাকিং এর জন্য ব্যবহৃত শেলকোড ইত্যাদি। ভাইরাস এবং এই শেলকোড যেগুলো স্ব-পরিবর্তনকারী কোড ব্যবহার করে সেগুলো সাধারণত পলিমরফিক কোড ব্যবহার করে লুকায়িত কোডটি আসল কোডের সাথে যুক্ত করা হয়। একটি কোড কাজ করার সময় কোডে পরিবর্তন করে সেই কোড কম্পিউটার হ্যাকিং করার জন্য ব্যবহার করা যায়। বাফার ওভারফ্লো হচ্ছে এর একটি উৎকৃষ্ট উদাহরণ।

### স্ব-উল্লেখ মেশিন লার্নিং সিস্টেম

গতানুগতিক মেশিন লার্নিং সিস্টেমে সাধারণত একটি নির্দিষ্ট এবং পূর্বে প্রোগ্রাম করা অ্যালগরিদম ব্যবহার করা হয়। অতঃপর ১৯৮০ সালে জর্জেন স্কিম্বার বেশ কয়েকটি স্ব-পরিবর্তনকারী কোডের নিয়ম আবিষ্কার করেন যেগুলো নিজে নিজেই তাদের নিজস্ব অ্যালগরিদমে পরিবর্তন ঘটাতে পারতো। এমনকি এটি কোডের জন্য বিপজ্জনক যেকোনো কোডের ব্যাপারে সতর্ক ছিল এবং যেকোনো প্রকার বিপজ্জনক কোড সহজেই মুছে ফেলতে পারতো। কোডের এই স্ব-পরিমার্জন এই বিষয়টি নিশ্চিত করে যে, ব্যবহারকারী যদি সঠিকভাবে ফিটনেস, এরর অথবা রিওয়ার্ড ফাংশন ব্যবহার করে কেবলমাত্র তাহলেই কোডে স্ব-পরিমার্জন ঘটবে।

### অপারেটিং সিস্টেম

যেহেতু কোডে স্ব-পরিমার্জনের ফলে কম্পিউটারের নিরাপত্তা বিঘ্নিত হওয়ার সম্ভাবনা থাকে, সুতরাং প্রায় সকল অপারেটিং সিস্টেমেই স্ব-পরিবর্তনকারী কোড পাওয়ামাত্রই সেটি মুছে দেয়। কোডটির নিজে থেকে  স্ব-পরিমার্জন বৈশিষ্ট্য থাকার জন্য নয়, বরং এই কোডটি কম্পিউটারের ক্ষতি করার সম্ভাবনা থাকে বলেই অপারেটিং সিস্টেম কোডটি মুছে দেয়।

এর ফলে কম্পিউটারে অনেক সমস্যা হতে পারে। সুতরাং এই সমস্যাটি সমাধান করার জন্য অপারেটিং সিস্টেমগুলো নতুন একটি ফিচার তৈরি করে। এর নাম দেয়া হয়  W^X ("রাইট এক্সওআর এক্সিকিউট" করার জন্য)। এটি মূলত ঐ সকল প্রোগ্রামগুলোকে কাজ করতে বাধা দেয়, যেগুলো স্ব-পরিবর্তনকারী কোড ব্যবহার করার সময় কোডে কোনরূপ পরিবর্তন করে।
কোন প্রোগ্রামে যদি কোড পরিবর্তনের ব্যাপারটি নিষেধ না থাকে, তাহলেই কিছু কিছু অপারেটিং সিস্টেম সরাসরি ঐ প্রোগ্রামটি এক্সিকিউট করতে বাধা দেয়। অন্যান্য অপারেটিং সিস্টেমগুলোতে 'ব্যাক ডোর' নামক অপশন থাকে, যার মাধ্যমে বিভিন্ন প্রোগ্রামে দেওয়া পারমিশন সম্পর্কে সিস্টেম অবহিত থাকে। এই W^X ফিচারটি এড়িয়ে যাওয়ার সবচেয়ে সহজ উপায় হল সকল পারমিশন দিয়ে একটি ফাইল তৈরি করা এবং তারপর সেটি মেমরিতে দুইবার রাখা। লিনাক্সে এটি ছাড়াও কেউ ইচ্ছা করলে একটি অনথিভুক্ত সিসভি মেমোরি ফ্ল্যাগ তৈরি করেও এই ফিচারটি সহজে এড়িয়ে যাওয়া যায়। এই পদ্ধতিটি ব্যবহার করলে নতুন কোন ফাইল তৈরী করতে হয়না।

এছাড়াও কম্পিউটার পলিমরফিজম ব্যবহার করে প্রোগ্রামের সর্বত্র ব্যবহার করা নিজস্ব ডেটা পরিবর্তন করেও প্রোগ্রামের কর্মপদ্ধতি নিজে নিজেই পরিবর্তন করতে পারে।

### ক্যাশ এবং স্ব-পরিবর্তনকারী কোডের মিথষ্ক্রিয়া

আর্কিটেকচারে ডেটা এবং নির্দেশ মিলিত হয়ে ক্যাশে জমা হয় এবং এই মিথষ্ক্রিয়া করার জন্য ক্যাশ সিঙ্ক্রোনাইজেশন অবশ্যই পরিবর্তিত কোড দ্বারা সঞ্চালিত করতে হবে।

আধুনিক প্রসেসরে কিছু কিছু ক্ষেত্রে স্ব-পরিবর্তনশীল কোড খুব ধীরে কাজ করে। এর কারণ হল, আধুনিক প্রসেসর সাধারণত তার ক্যাশ মেমরিতে এক্সিকিউট হওয়া কোডগুলো রাখার চেষ্টা করে। প্রতিবার প্রোগ্রাম যখন এর একটি অংশ একটু পরিবর্তন করে, তখন পুনর্লিখিত অংশ আবার ক্যাশের মধ্যে লোড করার দরকার হয়। যদি পরিবর্তীত কোড এবং পূর্বের কোড একই ক্যাশ মেমরি ব্যবহার করে, তাহলে ফলাফল আসতে সামান্য বিলম্ব হয়।  কারণ এখানে পরিবর্তীত কোডটির মেমরি অ্যাড্রেস পূর্বের কোডের অ্যাড্রেসের কয়েক বাইটের মধ্যেই অবস্থান করে।

আধুনিক প্রসেসরের ক্যাশ বিষয়ক  এই সমস্যাটি তখনই সমাধান হবে, যখন স্ব-পরিবর্তনশীল কোডগুলো তাদের কোড খুব কম সময় পরিবর্তন করে। যেমন, ইনার লুপের ভিতরে যেভাবে লুপ পরিবর্তন হয় সেভাবে।

অধিকাংশ আধুনিক প্রসেসরই কোন একটি প্রোগ্রাম এক্সিকিউট করার আগেই ঐ প্রোগ্রামটির সম্পূর্ণ মেশিন কোড মেমরিতে লোড করে নেয়। এর মানে যদি একটি কোড পূর্বের কোডের চেয়ে খুব কম পরিমাণে পরিবর্তন করা হয়, তাহলে প্রসেসর সেটি লক্ষ্য করবে না। কম্পিউটারের প্রসেসরগুলো অবশ্যই সঠিকভাবে স্ব-পরিবর্তনশীল কোড নিয়ন্ত্রণ করতে হবে, কিন্তু তারা এখনো সেটি করতে পারছে না।

### ম্যাসালিন এর সংশ্লেষণ কার্নেল

ডক্টর অ্যালেক্সিয়া ম্যাসালিনের পিএইচডি থিসিসে তিনি  সংশ্লেষণ কার্নেলের ব্যাপারে গবেষণা করেন। তিনি একটি ক্ষুদ্র ইউনিক্স কার্নেল ব্যবহার করে একটি স্ব-পরিবর্তনশীল কোড তৈরি করেন। এটি স্ট্রাকচার্ড প্রোগ্রামিং ভাষা এবং অবজেক্ট ওরিয়েন্টেড উভয় ভাষাতেই করা যায়। তার এই কোডটি সহজেই বিভিন্ন অবজেক্ট তৈরি করতে পারতো, যেমন ফাইল হ্যান্ডেলার।

এই সংশ্লেষণ কার্নেলটি অত্যন্ত দ্রুতগতির ছিল, কিন্তু এটি সম্পূর্ণরূপে অ্যাসেম্বলি ভাষায় লেখা হয়েছিল। ফলে এটি আর অন্য কোন ভাষায় অপটিমাইজ করতে না পারায়, এটি তেমন জনপ্রিয় হয়নি। যাইহোক, এটি একটি বিষয় প্রমাণ করেছিল যে, স্ব-পরিবর্তনশীল কোড যেকোনো মধ্য স্তর কিংবা উচ্চ স্তরের প্রোগ্রামিং ভাষায় লিখা সম্ভব। এতে করে আরও সহজেই খুব দ্রুতগতির বিভিন্ন অপারেটিং সিস্টেম অথবা প্রোগ্রাম তৈরি করা যাবে।

পল হাবার্লি এবং ব্রুস কার্শ স্ব-পরিবর্তনশীল কোডের প্রান্তিকীকরণের বিরোধিতা করেন। তাদের মতে এতে করে বিভিন্ন অপারেটিং সিস্টেম অথবা প্রোগ্রাম তৈরিতে খরচের পরিমাণ বৃদ্ধি পাবে।বহার করা হয়।

## উপাদানসমূহ

### সিনট্যাক্স

প্রোগ্রামিং ভাষার বই
কোন প্রোগ্রামিং ভাষার বাইরের রূপকে তার সিনট্যাক্স বলা হয়। বেশির ভাগ প্রোগ্রামিং ভাষাই সম্পূর্ণ টেক্সট-ভিত্তিক। এগুলি শব্দ, সংখ্যা ও বিরামচিহ্নবিশিষ্ট টেক্সট ব্যবহার করে, অনেকটা স্বাভাবিক ভাষাগুলির মতই। তবে কিছু কিছু প্রোগ্রামিং ভাষা আছে যেগুলি চিত্রভিত্তিক। এগুলি বিভিন্ন প্রতীকের মধ্যকার অবস্থানগত সম্পর্ক কাজে লাগিয়ে প্রোগ্রাম লিখতে সহায়তা করে।

কোন প্রোগ্রামিং ভাষার প্রতীকগুলি কী কী উপায়ে একত্রিত হয়ে সিনট্যাক্সগতভাবে সঠিক প্রোগ্রাম তৈরি করতে পারে, ভাষাটির সিনট্যাক্সে তার বিবরণ থাকে। আর কোন প্রতীকসমষ্টির অর্থ কী হবে, তা নির্ধারণ করে ভাষাটির সেমান্টিক্‌স।

প্রোগ্রামিং ভাষার সিনট্যাক্স সাধারণত নিয়মিত এক্সপ্রেশন (regular expression) (আভিধানিক বিশ্লেষণ|আভিধানিক গঠনের জন্য) এবং বাকাস-নাউর রূপ (Backus-Naur Form) (ব্যাকরণিক গঠনের জন্য) এই দুইয়ের সমন্বয়ে তৈরি করা হয়।

নিচে লিস্পের ওপর ভিত্তি করে লেখা একটি সরল ব্যাকরণ দেয়া হল:

`expression ::= atom | list

atom ::= number | symbol

number ::= [+-]?['0'-'9']+

symbol ::= ['A'-'Z''a'-'z'].*

list ::= '(' expression* ')'`

উপরের ব্যাকরণটি নিচের জিনিসগুলিকে সংজ্ঞায়িত করেছে:

* একটি *expression* হয় একটি *atom* অথবা একটি *list*;
* একটি *atom* হয় একটি *number* অথবা একটি *symbol*;
* একটি *number* হচ্ছে এক বা একাধিক দশমিক অঙ্কের অবিভক্ত ধারা, এবং ধারাটির আগে ঐচ্ছিকভাবে যোগ বা বিয়োগ চিহ্ন বসানো যেতে পারে;
* একটি *symbol* হচ্ছে একটি ইংরেজি বর্ণ এবং তাকে অনুসরণকারী শূন্য বা তার বেশি যেকোন সংখ্যক ক্যারেক্টার (ফাঁকাস্থান ব্যতীত); এবং
* একটি *list* হচ্ছে একজোড়া বন্ধনীর মধ্যে শূন্য বা তার বেশি সংখ্যক *expression*।

এই ব্যাকরণ সঠিকভাবে অনুসরণকারী কিছু টোকেনের উদাহরণ: '`12345`', '`()`', '`(a b c232 (1))`'

সিনট্যাক্সগতভাবে সঠিক প্রোগ্রাম মাত্রেই সেমান্টিক্‌স বা অর্থগতভাবে সঠিক হবে, তা নয়। অনেক সিনট্যাক্সগতভাবে সঠিক প্রোগ্রাম তাই অনুবাদ বা নির্বাহ করার সময় ত্রুটির সৃষ্টি করতে পারে। কোন কোন ক্ষেত্রে এরকম প্রোগ্রাম অসংজ্ঞায়ির আচরণ (undefined behavior) প্রদর্শন করতে পারে। আবার কোন প্রোগ্রাম প্রোগ্রামিং ভাষার সমস্ত নিয়মকানুন মেনে চললেও এটি প্রোগ্রামার যা করতে চেয়েছিলেন সেই অর্থে না-ও বাস্তবায়িত হতে পারে।

মানুষের মুখের স্বাভাবিক ভাষাতেও এর উদাহরণ মেলে। কোন ব্যাকরণগতভাবে শুদ্ধ বাক্য অর্থহীন হতে পারে, যেমন:

* "Colorless green ideas sleep furiously." - এই ইংরেজি বাক্যটি ব্যাকরণগতভাবে শুদ্ধ কিন্তু এর কোন সর্বজনগৃহীত অর্থ নেই।
* "John is a married bachelor." - এই বাক্যটি ব্যাকরণগতভাবে শুদ্ধ কিন্তু এমন একটি অর্থ প্রকাশ করে যা সত্য নয়।

নিচের সি প্রোগ্রামিং ভাষায় লেখা কোডটি সিনট্যাক্সগতভাবে শুদ্ধ, কিন্তু এটি এমন একটি অপারেশন সম্পাদন করে যা সেমান্টিক্‌সগতভাবে বা অর্থগতভাবে সংজ্ঞায়িত নয়। (যেহেতু p একটি নাল পয়েন্টার, p->real এবং p->im অপারেশনগুলি অর্থহীন):

```
complex *p = NULL;
complex abs_p = sqrt (p->real * p->real + p->im * p->im);
```

### টাইপ ব্যবস্থা

যেকোন প্রোগ্রামিং ভাষা মান (values) ও এক্সপ্রেশনগুলিকে বিভিন্ন “টাইপে” শ্রেণিকরণ করে। এই শ্রেণিকরণ, কীভাবে টাইপগুলি ব্যবহার করা যাবে এবং টাইপগুলির একে অপরের সাথে সম্পর্ক কী, তা সংজ্ঞায়িত থাকে প্রোগ্রামিং ভাষাটির টাইপ ব্যবস্থায়। ভাষাটিতে কী ধরনের উপাত্ত কাঠামো ব্যবহার করা যাবে, টাইপ ব্যবস্থায় মূলত তারই বিবরণ থাকে। বিধিগত গণিত ব্যবহার করে টাইপ ব্যবস্থাগুলি ডিজাইন ও গবেষণা “টাইপ তত্ত্বের” আলোচ্য।

আধুনিক ডিজিটাল কম্পিউটারের ভেতরে সমস্ত উপাত্তই শূন্য বা এক আকারে রক্ষিত থাকে (দ্বিমিক সংখ্যা ব্যবস্থা দেখুন)। এই উপাত্ততে বাস্তব বিশ্বের নানা তথ্য যেমন নাম, ব্যাংক অ্যাকাউন্ট, পরিমাপ, ইত্যাদি প্রকাশ পেতে পারে। প্রোগ্রামিং ভাষা নিম্নস্তরের দ্বিমিক উপাত্তকে এই উচ্চ-স্তরের তথ্যের ধারণায় বাস্তবায়ন করে উপাত্ত টাইপের সাহায্য নিয়ে। এছাড়া আরও কিছু বিমূর্ত টাইপ আছে যেগুলি প্রোগ্রামের নিরাপত্তার সুবিধার্থে কিংবা প্রোগ্রামারকে অর্থহীন বিবৃতির ব্যাপারে সাবধান করে দেয়ার জন্য ব্যবহৃত হয়।

প্রোগ্রামিং ভাষাগুলিকে তাদের টাইপ ব্যবস্থাগুলির ওপর ভিত্তি করে শ্রেণিবিভাগ করা যায়।

#### টাইপকৃত বনাম অ-টাইপকৃত ভাষা

কোন প্রোগ্রামিং ভাষার একটি উপাত্ত টাইপের জন্য সংজ্ঞায়িত অপারেশনগুলি যখন অন্য একটি উপাত্ত টাইপের ওপর প্রয়োগ করা যায় না, তখন সেই ভাষাটিকে “টাইপকৃত ভাষা” বলা হয়। উদাহরণস্বরূপ, "`this text between the quotes`" একটি স্ট্রিং। বেশির ভাগ প্রোগ্রামিং ভাষায় স্ট্রিং-কে কোন সংখ্যা দিয়ে ভাগ করা অর্থহীন। তাই বেশির ভাগ ভাষাতে কোন প্রোগ্রামকে এই ধরনের অপারেশন সম্পাদন করতে বাধা দেয়া হয়। কিছু কিছু ভাষায় এই অর্থহীন অপারেশনটি প্রোগ্রামটি কম্পাইল করার সময় ধরা হয়; একে বলা হয় “স্থির টাইপ পরীক্ষা” (static type checking), এবং কম্পাইলার অপারেশনটি প্রত্যাখ্যান করে। আবার অন্য কিছু ভাষায় এই ধরনের অপারেশন যখন প্রোগ্রামটি চালানো হয় বা “রান” করা হয়, তখন ধরা হয়; একে বলা হয় “চলমান টাইপ পরীক্ষা” (dynamic type checking), এবং এতে “রান-টাইম” এক্সেপশন সৃষ্টি হয়।

#### নিম্নস্তরের ভাষা

নিম্নস্তরের ভাষা(low level language) সরাসরি কম্পিউটারের প্রধান মেমোরির উপর কাজ করতে পারে। অ্যাসেম্বলি ভাষা একটি নিম্নস্তরের ভাষা,এ ভাষায় সরাসরি কম্পিউটারের রেজিস্টারকে নিয়ন্ত্রণ করে কাজ করতে হয়। এ ভাষাগুলো হার্ডওয়্যারের উপর নির্ভরশীল,তাই এক কম্পিউটারে অ্যাসেম্বলি ভাষায় লেখা প্রোগ্রাম অন্য কম্পিউটারে কাজ নাও করতে পারে।

## তথ্যসূত্র