ভূমিকা
সবাইকে স্বাগতম! আশা করি আপনারা সবাই ভালো আছেন।
Exercism-এ গত কয়েক সপ্তাহ সত্যিই দারুণ উত্তেজনাকর ছিল, বিশেষ করে Exercism Premium আর Exercism Insiders চালু হওয়ায়। আমাদের বেশ কিছু দারুণ কমিউনিটি কলও হয়েছে, আর সাইটে অনেক উন্নতি ইতিমধ্যেই ডিপ্লয় হয়েছে এবং আরও আসছে। এই মুহূর্তে উত্তেজনার অনেক কারণ আছে, তবে তার মধ্যে সবচেয়ে উত্তেজনাকর হলো আমরা #12in23-এর ৬ষ্ঠ মাসে পা রাখছি, অর্থাৎ এস-এক্সপ্রেশনের গ্রীষ্ম, যা আরও সুন্দরভাবে ছোট করে বলা হয় Summer of Sexps।
বরাবরের মতো, প্রোগ্রামিং জগতের জ্ঞানী ঋষি এরিক আমার সঙ্গে আছেন।
তো, এই মাসে আমাদের হাতে পাঁচটি ভাষা আছে: Clojure, Common Lisp, Emacs Lisp, Racket আর Scheme। এই প্রতিটি ভাষাই Lisp ভাষার একটি উপভাষা, তাই এই ভিডিওতে আলাদা আলাদা ভাষার দিকে খুব বেশি মনোযোগ না দিয়ে আমরা বরং Lisp নিজের দিকে, আর তাকে কী অনন্য করে তোলে সেদিকে একটু বেশি নজর দেব। তারপর শেষে আমরা সংক্ষেপে ভাষাগুলো একবার দেখে নেব।
কিন্তু তার আগে, কিছু প্রয়োজনীয় কথা! Summer of Sexps ব্যাজ পেতে হলে জুন মাসে ওই ভাষাগুলোর যেকোনো একটি ভাষায় যেকোনো পাঁচটি অনুশীলনী সম্পূর্ণ করতে হবে।
ব্যাজগুলো
এছাড়া সারা বছরব্যাপী 12in23 ব্যাজও আছে। সেটি পেতে হলে আপনার ভাষার পাঁচটি নির্বাচিত অনুশীলনী সমাধান করতে হবে। আপনি যদি জুনের পরে এটি দেখেন, তাহলে বছরের যেকোনো সময় এই অংশটি করতে পারবেন, তাই আপনার কিছুই হাতছাড়া হয়নি। যেহেতু অনেকেই এর আগে কখনো Lisp নিয়ে কাজ করেননি, আমরা তুলনামূলক সহজ কিছু অনুশীলনী বেছে নেওয়ার চেষ্টা করেছি, যেগুলো Lisp ভাষা কেমন দেখতে হয় তার একটু আভাস দেবে।
- লিপ: বুলিয়ান শর্ত আর ট্রুথিনেস নিয়ে কাজ (এবং চাইলে লেক্সিকাল স্কোপিংও)
- টু-ফার: একটি স্ট্রিং ফরম্যাট করা আর একটি ঐচ্ছিক প্যারামিটার নিয়ে কাজ
- ডিফারেন্স অফ স্কয়ার্স: ব্যবহারকারীর ডিফাইন করা ফাংশন কল করা আর প্রিফিক্স নোটেশনে গণিত করা
- রোবট নেম: র্যান্ডমনেস, অ্যাটম আর স্ট্রাকচার্ড ডেটা নিয়ে কাজ
- ম্যাচিং ব্র্যাকেটস: স্ট্রিং যাচাই করতে রিকার্সন ব্যবহার করা
এই অনুশীলনীগুলো আর আগের মাসগুলোর অনুশীলনীগুলো সবই #12in23 পেজে পাওয়া যাবে।
এক নজরে
তো, Lisp-ভিত্তিক ভাষা। আমার মনে হয়, শুরু করা উচিত Lisp সম্পর্কে অন্তত একটু বুঝে নেওয়া দিয়ে। চলুন, সাধারণভাবে Lisp-এর একটি ছোট্ট পরিচিতি দিয়ে শুরু করি।
Lisp
-
প্রথমেই যে বিষয়টি খেয়াল করার মতো, তা হলো Lisp সবচেয়ে পুরনো ভাষাগুলোর একটি।
-
এটি ১৯৫৮ সালে MIT-তে জন ম্যাকার্থি তৈরি করেছিলেন, সেই সময়ে কম্পিউটার পুরো ঘর তল থেকে ছাদ পর্যন্ত দখল করে থাকত 🙂
-
Lisp নামটি এসেছে LISt Processing (বা LISt Processor) থেকে, যা লিস্ট ডেটা স্ট্রাকচারের গুরুত্ব তুলে ধরে।
-
এটি তৈরি করা হয়েছিল AI গবেষণার উদ্দেশ্যে।
-
Lisp ভিত্তি করে তৈরি হয়েছিল ল্যাম্বডা ক্যালকুলাসের উপর, যা আলোনজো চার্চ আবিষ্কার করেছিলেন এবং যা গণিতে কম্পিউটেশন বর্ণনা করার একটি আনুষ্ঠানিক পদ্ধতি (সরল করে বললে)।
-
এটি অবিশ্বাস্যভাবে প্রভাবশালী একটি ভাষা, নানা কারণে:
-
এখনও কমন ব্যবহারে থাকা উচ্চ-স্তরের প্রোগ্রামিং ভাষাগুলোর মধ্যে এটি দ্বিতীয় প্রাচীনতম (Fortran-এর পরে)
-
এটি ছিল প্রথম উচ্চ-স্তরের ফাংশনাল প্রোগ্রামিং ভাষা এবং এটি এমন অনেক বৈশিষ্ট্য নিয়ে এসেছিল যেগুলোকে আমরা এখন ফাংশনাল প্রোগ্রামিংয়ের সঙ্গে যুক্ত করি।
-
খেয়াল করুন, Lisp কিন্তু ইম্পারেটিভ প্রোগ্রামিংও সমর্থন করত
-
এটিই ছিল গার্বেজ কালেক্টরযুক্ত প্রথম ভাষা, যা লেখককে ম্যানুয়াল মেমরি ম্যানেজমেন্টের ঝামেলা থেকে মুক্তি দিয়েছিল
-
এর তুলনামূলক কম সিনট্যাক্স আর তুলনামূলক সরল সিম্যান্টিকস এটিকে শিক্ষার উদ্দেশ্যে দারুণ উপযোগী করে তোলে।
-
তাই প্রোগ্রামিং শেখানোর জন্য প্রায়ই Lisp (বা আরও ভালোভাবে বললে, এর কোনো একটি উপভাষা) ব্যবহার করা হয়
-
এটি অসংখ্য ভাষা-উপভাষার জন্ম দিয়েছে (এবং এখনও দিচ্ছে!), যার মধ্যে Exercism-এ সমর্থিতগুলো নিয়ে আমরা আলোচনা করব।
-
অন্য কথায়, প্রোগ্রামিং ভাষার বৃক্ষে Lisp-সদৃশ ভাষার জন্য আলাদা একটি শাখা আছে (যেমনটি C-সদৃশ ভাষার জন্যও একটি শাখা আছে)।
সম্প্রতি যখন আমি Haskell-এর একজন নির্মাতা সায়মন পেটন জোন্সের সঙ্গে কথা বলি, তখন তিনি টুরিং মেশিন-ভিত্তিক ভাষা আর ল্যাম্বডা ক্যালকুলাস-ভিত্তিক ভাষার পার্থক্য নিয়ে কথা বলছিলেন। তাই এই বিষয়ে আরও জানতে চাইলে ওই ইন্টারভিউটি একবার দেখে নেওয়া যেতে পারে।
বন্ধনী
Lisp-এ প্রচুর বন্ধনী থাকে, কিন্তু সেটা সবসময় খারাপ কিছু নয় (যেমন C-সদৃশ ভাষায় অনেক কার্লি ব্রেস থাকাও খারাপ কিছু নয়)। Lisp তৈরি হয়েছে S-এক্সপ্রেশন নামের একটি জিনিসকে ঘিরে। একটি S-এক্সপ্রেশন (symbolic expression-এর সংক্ষিপ্ত রূপ, সংক্ষেপে sexpr বা sexp, আর সেখান থেকেই এই মাসের চ্যালেঞ্জের নাম) হলো ডেটা প্রকাশ করার একটি এক্সপ্রেশন। এগুলো মূল Lisp ভাষার জন্য উদ্ভাবিত হয়েছিল এবং সেই ভাষার হাতেই জনপ্রিয়তা পেয়েছিল। একটি S-এক্সপ্রেশন দুই ধরনের হতে পারে:
- একটি অ্যাটম (যেমন 'x')। এগুলোকে নেস্টেড নয় এমন "মান" বা বৃক্ষের পাতা হিসেবে ভাবুন
- একটি এক্সপ্রেশন x . y, যেখানে x আর y দুটোই S-এক্সপ্রেশন। এগুলোকে জোড়া হিসেবে ভাবুন, যেখানে y হতে পারে লিস্টের পরের এলিমেন্ট (যদি থাকে), বা বৃক্ষের নোড। খেয়াল করুন, এটি একটি রিকার্সিভ সংজ্ঞা, যা পাতার স্তরে এসে থেমে যায়। সাধারণত এই ধরনের S-এক্সপ্রেশনের জন্য বন্ধনী ব্যবহার করা হয়।
S-এক্সপ্রেশন
Lisp-এ ডেটা আর লিস্ট দুটোই প্রকাশ করতে S-এক্সপ্রেশন ব্যবহার করা হয়। তাই যখনই আপনি একটি লিস্ট ডিফাইন করবেন, বন্ধনী ব্যবহার করবেন। এর সঙ্গে যোগ করুন এই বিষয়গুলো: লিস্টই Lisp-এর মূল ডেটা স্ট্রাকচার (নামটাই তাই বলে), কিছু Lisp-এ এটি একমাত্র ডেটা স্ট্রাকচার, ফলে প্রচুর বন্ধনী দাঁড়িয়ে যাবে। লিস্ট কতটা মূল বিষয়, তা বোঝাতে বলি: Lisp-এ কোনো ফাংশন কল করতে চাইলে সেটা করতে হয় একটি লিস্ট তৈরি করে।
মজার ব্যাপার হলো, লিস্টের প্রথম এলিমেন্টটি (যাকে head বা মাথা বলা হয়) কল করা ফাংশনটিকে বোঝায়, আর বাকি এলিমেন্টগুলো (যাকে tail বা লেজ বলা হয়) আর্গুমেন্ট হিসেবে পাস করা হয়। একে প্রিফিক্স নোটেশন বলা হয় (যেখানে অপারেটর অপারেন্ডের আগে আসে), যা প্রথমে একটু অদ্ভুত লাগতে পারে, কিন্তু আসলে খুবই কাজের:
- অপারেটরটি বারবার না লিখেই একাধিক আর্গুমেন্টে একটি অপারেটর প্রয়োগ করতে পারেন (যেমন (+ 1 2 3))
- অপারেটরের প্রাধান্য স্পষ্ট হয়ে যায়, কারণ ভিন্ন কোনো অপারেটর কল করতে হলে যেভাবেই হোক একটি নতুন S-এক্সপ্রেশন ডিফাইন করতে হয়
আরও মজার ব্যাপার, সোর্স কোড প্রকাশ করতেও লিস্ট ব্যবহার করা হয়, কিন্তু সেদিকে আমরা পরে ফিরে আসব।
সাধারণভাবে বেশিরভাগ Lisp-এর সিনট্যাক্স বেশ সংক্ষিপ্ত আর সিম্যান্টিকস তুলনামূলক সরল, যা এগুলো শেখা তুলনামূলক সহজ করে তোলে, আর কোড বোঝাও সহজ হয়ে যায়। কম সিনট্যাক্স মানেই এগুলো কম শক্তিশালী নয়! এই দুটি জিনিস একসঙ্গে (সংক্ষিপ্ত সিনট্যাক্স + সরল সিম্যান্টিকস) Lisp-কে কম্পাইলার আর ইন্টারপ্রেটার লেখার জন্য আদর্শ করে তোলে। কখনো যদি নিজের কম্পাইলার বানাতে চান, তাহলে একটি Lisp বানানো ভালো একটি বিকল্প!
Lisp-এর দারুণ কিছু বৈশিষ্ট্য
আগেই বলা হয়েছে, Lisp কোড প্রকাশ করতে ভেতরে একই ডেটা টাইপ আর ডেটা স্ট্রাকচার ব্যবহার করে। এই বৈশিষ্ট্যকে বলা হয় হোমোআইকনিসিটি (বা হোমোআইকনিক)। অন্য কথায়, একটি ভাষা হোমোআইকনিক হয় তখনই, যখন সেই ভাষায় লেখা একটি প্রোগ্রামকে ওই ভাষা দিয়েই ডেটা হিসেবে নাড়াচাড়া করা যায়, ফলে প্রোগ্রামটি নিজেই পড়ে নিলেই তার অভ্যন্তরীণ রূপ অনুমান করা যায়। এই বৈশিষ্ট্যকে প্রায়ই সংক্ষেপে বলা হয় যে, ভাষাটি কোডকে ডেটা হিসেবে দেখে।
ভাষাগুলো
Scheme
- ১৯৭০-এর দশকে MIT AI Lab-এ গাই স্টিল আর জেরাল্ড সাসম্যান এটি তৈরি করেন।
- শুরু হয়েছিল কার্ল হিউইটের অ্যাক্টর মডেল বোঝার এক প্রচেষ্টা হিসেবে, ছোট্ট একটি Lisp ইন্টারপ্রেটারের মাধ্যমে।
- ভাষাটি নিজে পরিচিত হয়েছিল একগুচ্ছ গবেষণা AI Memo-র মাধ্যমে, যেগুলোকে একসঙ্গে Lambda Papers নামে ডাকা হয়।
- লেক্সিকাল স্কোপিং ব্যবহার করা প্রথম Lisp উপভাষা (মান কেবল সেখানেই স্কোপে থাকে যেখানে সেগুলো ডিফাইন করা হয়েছে) এবং ফার্স্ট-ক্লাস কন্টিনিউয়েশন সমর্থন করা প্রথম ভাষাগুলোর একটি।
- IEEE-র আনুষ্ঠানিক স্ট্যান্ডার্ড, আর Revised Report on the Algorithmic Language Scheme (RnRS) নামে একটি ডি ফ্যাক্টো স্ট্যান্ডার্ড।
- অনেক রকম ইমপ্লিমেন্টেশন: ChezScheme, Guile (দুটোই Exercism-এ সমর্থিত), MIT/GNU Scheme আর Racket
- খুবই সংক্ষিপ্ত ভাষা, সিনট্যাক্স সামান্যই, তবে সেটি ইচ্ছাকৃত ছিল না।
- নির্মাতারা জটিল কিছু বানানোর চেষ্টা করেছিলেন, কিন্তু শেষে তাঁরা যা চেয়েছিলেন তার চেয়ে অনেক সরল কিছু ডিজাইন করে ফেলেন
- যথাযথ tail recursion। ইটারেশন করার প্রচলিত রীতি হলো রিকার্সনের মাধ্যমে।
- Scheme tail recursive কল অপ্টিমাইজ করে, যাতে স্ট্যাক স্পেস বা অন্য রিসোর্স খরচ না হয়। এর মানে হলো, ইচ্ছেমতো বড় ডেটা বা ইচ্ছেমতো দীর্ঘ হিসাবেও রিকার্সন ব্যবহার করা যায়
- শক্তিশালী নিউমেরিক ডেটা টাইপ, যার মধ্যে মূলদ আর জটিল সংখ্যাও আছে
- ডিলেইড ইভালুয়েশন, যা অনেকটা প্রমিসের মতো।
- শক্তিশালী ম্যাক্রো সিস্টেম।
- হাইজেনিক ম্যাক্রো ডিফাইন করার সময় অনাকাঙ্ক্ষিত ফলাফলের সম্ভাবনা কমিয়ে দেয়।
Common Lisp
- Common Lisp-এর কাজ শুরু হয় ১৯৮১ সালে, ARPA-র ম্যানেজার বব এঙ্গেলমোরের একটি উদ্যোগের পর, যার লক্ষ্য ছিল একটি একক কমিউনিটি-স্ট্যান্ডার্ড Lisp উপভাষা গড়ে তোলা, কারণ তখন ব্যবহৃত নানা উপভাষা প্রায়ই বেমানান ছিল, ফলে কোড বা জ্ঞান ভাগাভাগি করা যেত না
- প্রথম স্ট্যান্ডার্ড প্রকাশিত হয় ১৯৮৪ সালে আর চূড়ান্তটি ১৯৯৪ সালে (খুবই স্থিতিশীল স্পেক)
- যেহেতু এটি একটি স্ট্যান্ডার্ড, তাই স্ট্যান্ডার্ডটির নানা ইমপ্লিমেন্টেশন আছে, যেমন Steel Bank Common Lisp (যা Exercism-এর ডিফল্ট) আর CLisp।
- বাণিজ্যিক ইমপ্লিমেন্টেশনও আছে, যেমন Allegro CL আর LispWorks, পাশাপাশি ECL (Embeddable Common Lisp), যা C প্রোগ্রামে এমবেড করা যায়, আর ABCL, যা Java Virtual Machine-এ চলে।
- একটি স্ট্যান্ডার্ড (ANSI INCITS 226-1994) দিয়ে সংজ্ঞায়িত, তাই ৩০ বছর আগে লেখা কোডও আজও ভালোভাবে চলে
- সমৃদ্ধ ও সম্প্রসারণযোগ্য টাইপ সিস্টেম
- image আর REPL ডেভেলপমেন্টের কথা ভেবে ডিজাইন করা, তাই খুব সহজেই ইন্ট্রোস্পেক্ট করা যায়।
Emacs Lisp
- তৈরি করা হয় ১৯৮৫ সালে, একটি টেক্সট এডিটর সম্প্রসারণের জন্য দক্ষ একটি ভাষা পাওয়ার উদ্দেশ্যে
- ডাইনামিক্যালি টাইপড
- Emacs-এর প্রায় ৮০% লেখা হয়েছে Emacs Lisp-এ (পারফরম্যান্সের কারণে ২০% C-তে)
- অন্য Lisp-দের থেকে একটু আলাদা:
- স্ট্যান্ডার্ডাইজড নয়, এখনও ধীরে ধীরে বিবর্তিত হচ্ছে
- স্বয়ংক্রিয় tail-call elimination নেই, named-let ম্যাক্রোর মাধ্যমে সমর্থন (যা while-loop-এ রূপান্তরিত হয়)
- ডিফল্টভাবে ডাইনামিক স্কোপিং, নতুন কোডের জন্য লেক্সিকাল স্কোপিং সুপারিশ করা হয়
- এডিটরের ভেতরেই ভালো ডকুমেন্টেশন
- মাল্টি-প্ল্যাটফর্ম (Emacs যেখানেই চলে, সেখানেই চলে)
- প্রতিদিন যে ফিচারগুলো ব্যবহার করেন, তার কোড পড়ে ভাষাটি শিখুন (Emacs Core + Packages)
- cl-lib প্যাকেজের মাধ্যমে Common Lisp-এর একটি উপসেট পাওয়া যায়। Emacs Lisp বেশ মিনিমালিস্ট, আর Common Lisp অনেক বেশি সুবিধাসম্পন্ন। cl-lib প্যাকেজ CL-এর একটি উপসেট ব্যবহারযোগ্য করে তোলে
Racket
- মাটিয়াস ফেলেইসেন PLT Inc. প্রতিষ্ঠা করেন, যা ১৯৯৫ সালের জানুয়ারিতে Scheme-ভিত্তিক একটি শিক্ষামূলক প্রোগ্রামিং পরিবেশ তৈরির সিদ্ধান্ত নেয়। শুরুতে এর নাম ছিল PLT Scheme, পরে নাম বদলে Racket করা হয়।
- শিক্ষামূলক প্রোগ্রামিং পরিবেশ হওয়ার পাশাপাশি এটি প্রোগ্রামিং ভাষার ডিজাইন ও ইমপ্লিমেন্টেশনের একটি প্ল্যাটফর্ম হিসেবেও ডিজাইন করা হয়েছিল।
- আধুনিক LISP, Scheme-এর উত্তরসূরি
- লজিক প্রোগ্রামিং সমর্থন করে!
- সরল, ভাবপ্রকাশী সিনট্যাক্স, যা একইসঙ্গে নতুনদের জন্য আদর্শ আর বিশেষজ্ঞদের হাতে শক্তিশালী
- অনেক প্রোগ্রামিং প্যারাডাইম সমর্থন করে: ফাংশনাল প্রোগ্রামিং, অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং, design by contract, লজিক প্রোগ্রামিং, মেটাপ্রোগ্রামিং
- সুবিস্তৃত স্ট্যান্ডার্ড লাইব্রেরি
- সঙ্গে আসে DrRacket, শেখা আর ঘাঁটাঘাঁটি করার জন্য তৈরি একটি সম্পূর্ণ IDE, যা ব্যবহারে ঝামেলা কম
- অসাধারণ ডকুমেন্টেশন, সঙ্গে প্রচুর পটভূমির তথ্য আর উদাহরণ
Clojure
- রিচ হিকি তৈরি করেন, যার লক্ষ্য ছিল JVM-এ চলে এমন একটি আধুনিক LISP, যাতে দুর্দান্ত কনকারেন্সি থাকবে
- LISP-এর উপভাষা, তবে অন্য LISP-দের থেকে কিছুটা আলাদা, কারণ এটি implicit tail recursion সমর্থন করে না (এটা কী জানা না থাকলে চিন্তার কিছু নেই) এবং এতে কেবল লিস্ট নয়, আরও ডেটা স্ট্রাকচার আছে: map/set/vector। এই ডেটা স্ট্রাকচারগুলোর প্রতিটির নিজস্ব literal syntax আছে।
- এগুলো সবই immutable, তবুও O(log32 n) লুকআপ নিয়ে দুর্দান্ত পারফরম্যান্স দেয়, যা "কার্যত" constant time
- multimethod আর protocol-এর মাধ্যমে runtime polymorphism
- দুর্দান্ত JVM interop
- Clojure Spec ডেটা স্পেসিফিকেশন সিস্টেম (রানটাইমে, কম্পাইল-টাইমে নয়), যা দিয়ে ডেটার গঠন ডিফাইন করা, ডেটা জেনারেট করা, property-based testing আরও অনেক কিছু করা যায়
ব্যবহারের ক্ষেত্র
Scheme
- শিক্ষায় কম্পিউটার সায়েন্স শেখাতে ব্যবহৃত হয় (প্রভাবশালী Structure and Interpretation of Computer Programs বইটি Scheme ব্যবহার করে)।
- AI-তে ব্যবহৃত হয়। স্ক্রিপ্টিং ভাষা হিসেবেও ব্যবহৃত হয়, যেমন GIMP-এ (গ্রাফিক্স এডিটর), CAD টুলে (Computer Aided Design) আর এমনকি সিনেমাতেও, যেমন Final Fantasy: The Spirit Within-এর রেন্ডারিং ইঞ্জিন ম্যানেজমেন্ট স্ক্রিপ্টে
Common Lisp
- Common Lisp অনেক জায়গায় ব্যবহৃত হয়, যেমন কৃত্রিম বুদ্ধিমত্তা আর গবেষণায়, পাশাপাশি বাণিজ্যিক অ্যাপ্লিকেশনেও: NASA তাদের Deep Space One মহাকাশযানের অটোপাইলটিং সফটওয়্যার লিখেছিল Common Lisp-এ, Viaweb-ও লেখা হয়েছিল Common Lisp-এ, যা পরে Yahoo কিনে নেয় আর Yahoo Store! নামে পুনঃব্র্যান্ড করে, আর Reddit-এর প্রথম সংস্করণও
Emacs Lisp
- Emacs Lisp ব্যবহৃত হয়, আরে, Emacs-এই!
- মূলত Emacs হলো Emacs Lisp-এর একটি ইন্টারপ্রেটার, যা Lisp প্রোগ্রামিং ভাষার একটি উপভাষা, তবে টেক্সট এডিটিং সমর্থনের জন্য বাড়তি এক্সটেনশন যোগ করা হয়েছে
Racket
- শিক্ষায় ব্যবহৃত হয়, কারণ Racket ডিজাইন করা হয়েছিল ভাষা তৈরি, সরলীকরণ আর বিশ্লেষণকে গুরুত্ব দিয়ে।
- গবেষণায় ব্যবহৃত হয়, কারণ এর সম্প্রসারণযোগ্য সিনট্যাক্স আর সিম্যান্টিকস এটিকে নতুন ভাষা ও ভাষার বৈশিষ্ট্য ডিজাইন ও প্রোটোটাইপ করার জন্য উপযুক্ত করে তোলে।
- গেমে ব্যবহৃত হয়, যেমন জন কারম্যাক (Doom-খ্যাত) VR-এর জন্য একটি ইন্টারঅ্যাকটিভ স্ক্রিপ্টিং পরিবেশে এটি ব্যবহার করেছিলেন, আর ডেভেলপার Naughty Dog স্ক্রিপ্টিংয়ের জন্য এটি ব্যবহার করেছিল (যেমন Uncharted-এ)। Hacker News লেখা হয়েছে Arc-এ, যেটিও একটি Lisp, আর Arc নিজেই লেখা হয়েছে Racket-এ।
Clojure
- Clojure নানা কাজে ব্যবহৃত হয়, যার মধ্যে আছে ২০২২ সালে Docker কর্তৃক Atomist অধিগ্রহণ, যেটি Clojure-এ তৈরি একটি কন্টেইনার সিকিউরিটি ও অটোমেশন প্ল্যাটফর্ম।
- Clojure-এর বিশ্বের বৃহত্তম ব্যবহারকারী হলো Nubank, একটি নতুন ব্যাংক, যারা কয়েক বছর আগে এটিকে নিজের করে নেয় আর এখন Clojure-এর মূল টিমকে নিয়োগ দিয়েছে।
- দ্রুত প্রোটোটাইপিংয়ের জন্য এটি ব্যাপকভাবে ব্যবহৃত হয়, কারণ এটি ডাইনামিক আর অত্যন্ত ইন্টারঅ্যাকটিভ।
প্রোগ্রামিংয়ের দৃষ্টিকোণ
সব ভাষাই ফাংশনাল, ইম্পারেটিভ আর সিম্বলিক প্যারাডাইম সমর্থন করে। এর মধ্যে কয়েকটি OOP-ও সমর্থন করে, বিশেষ করে Common Lisp।
Lisp-গুলো বেশিরভাগই ডাইনামিক ভাষা, যদিও Racket static typing সমর্থন করে।
এর মানে এই নয় যে এগুলো সবই ইন্টারপ্রেটেড, কারণ এখানে মিশ্রণ আছে: সরাসরি ইন্টারপ্রেটেড (কোনো কম্পাইলেশন ধাপ ছাড়াই), বাইটকোডে কম্পাইল হয়ে পরে ইন্টারপ্রেটেড, আর সরাসরি মেশিন কোডে কম্পাইল হওয়া।
Scheme
- মিনিমালিস্টিক, স্পষ্ট ও সরল সিম্যান্টিকস আর এক্সপ্রেশন গঠনের অল্প কয়েকটি উপায় নিয়ে।
- ভাষাটি শেখা আর কোড বোঝা সহজ করে তোলে।
- এ কারণেই কম্পিউটার সায়েন্সের অনেক প্রাথমিক কোর্সেও Scheme প্রায়ই ব্যবহৃত হয়
- ফার্স্ট-ক্লাস কন্টিনিউয়েশন।
- একটি কন্টিনিউয়েশন হলো একটি প্রোগ্রামের অবস্থার একটি রূপ।
- কন্টিনিউয়েশন দিয়ে কন্ট্রোল ফ্লো মডেল করা যায় (যেমন একটি
returnকনস্ট্রাক্ট) বা কোরুটিন (যা মাল্টিটাস্কিং সম্ভব করে)
Common Lisp
- প্রোগ্রামেবল মেথড কম্বিনেশনসহ সম্প্রসারণযোগ্য অবজেক্ট-ওরিয়েন্টেড সিস্টেম (সাব/সুপার-ক্লাস মেথড কীভাবে একত্রিত হয়, সেই সঙ্গে before, after আর around মেথড, যাতে সিস্টেমগুলো পরিবর্তন না করেই সেগুলো সম্প্রসারিত করা যায়)
- প্রোগ্রামেবল শর্ত সিস্টেম ('এক্সসেপশন'-এর একটি সুপারসেট), যা শর্ত চিনে নেওয়া আর সেগুলো কীভাবে সামলানো হবে তার সিদ্ধান্তকে আলাদা করতে দেয়। শর্ত সিস্টেম এক্সসেপশন সিস্টেমের চেয়ে বেশি নমনীয়, কারণ যে কোড এরর¹ সংকেত দেয় আর যে কোড সেটি সামলায়² এই দুই ভাগে ভাগ করার বদলে, শর্ত সিস্টেম দায়িত্বকে তিন ভাগে ভাগ করে: শর্তের সংকেত দেওয়া, সেটি সামলানো, আর পুনরায় শুরু করা।
- ম্যাক্রো দিয়ে ভাষার সিনট্যাক্স সম্প্রসারণ করা যায়, শুধু boilerplate কোড জেনারেট করা নয়। এটি ডোমেইন অনুযায়ী ভাষা গড়ে তুলতে সাহায্য করে, উল্টোটা নয়।
Emacs Lisp
- দুর্দান্ত এডিটর সাপোর্ট আর ইন্টিগ্রেশন
- Emacs চলমান অবস্থাতেই এটি দিয়ে কাস্টমাইজ করা যায় ("নিজের মাথার অস্ত্রোপচার নিজেই করার মতো" :))
- ব্যাচ মোডেও ব্যবহার করা যায়, যেখানে টেক্সট প্রসেস করার এডিটরের সব ক্ষমতা আপনার হাতে থাকে (যেমন বাফার আর মুভমেন্ট কমান্ড)
Racket
- শক্তিশালী ম্যাক্রো সিস্টেম। threading macro-এর মতো syntax sugar এটির উপরেই তৈরি। ম্যাক্রো হাইজেনিকও, যা একটি সরল প্রশ্নের উত্তর: একটি ম্যাক্রো এমন কোড তৈরি করে যা অন্যত্র গিয়ে বসে। সেই কোড ইভালুয়েট করার সময়, ভেতরের আইডেন্টিফায়ারগুলোর বাইন্ডিং আমরা কীভাবে নির্ধারণ করব? হাইজেনিক ম্যাক্রো ডিফাইন করার সময় অনাকাঙ্ক্ষিত ফলাফলের সম্ভাবনা কমিয়ে দেয়।
- ভাষা-কেন্দ্রিক।
- Racket-এর সঙ্গে আসে নিজের প্রোগ্রামিং ভাষা বা DSL লেখার টুল, যা Racket-এর ম্যাক্রোর উপর তৈরি।
- বেশ কিছু বিল্ট-ইন ভাষা, যেমন typed Racket (স্ট্যাটিকালি চেক করা টাইপ অ্যানোটেশন সমর্থন করে), datalog (Prolog-সদৃশ একটি ভাষা), যাকে DrRacket IDE সমর্থন করে, আর scribble, HTML বা PDF রূপে গদ্য ডকুমেন্ট তৈরির একটি টুল
- REPL ডেভেলপমেন্ট ওয়ার্কফ্লোর মূল অংশ, শুধু জিনিস পরখ করে দেখা বা ডক খোঁজার জন্য নয়
Clojure
- শক্তিশালী ম্যাক্রো সিস্টেম।
- threading macro-এর মতো syntax sugar এটির উপরেই তৈরি
- REPL ডেভেলপমেন্ট ওয়ার্কফ্লোর মূল অংশ, শুধু জিনিস পরখ করে দেখা বা ডক খোঁজার জন্য নয়
কোনটি চেষ্টা করবেন
- যদি আগে কখনো Lisp চেষ্টা না করে থাকেন, তাহলে Scheme আর Racket দারুণ বিকল্প, কারণ দুটিরই সিনট্যাক্স খুবই সংক্ষিপ্ত।
- তবে Common Lisp আর Clojure দুটিরই Learning Mode আছে, তাই Exercism-এ শেখার জন্য সম্ভবত এগুলোই সেরা।
- যদি ইতিমধ্যে Emacs ব্যবহার করেন, তাহলে Emacs Lisp স্বাভাবিক পছন্দ।
- একইভাবে, যদি JVM ভাষা ব্যবহার করেন, Clojure স্বাভাবিক বিকল্প।
- Emacs Lisp (Emacs-এর মাধ্যমে), Clojure (IntelliJ-এর মাধ্যমে) আর Racket (DrRacket-এর মাধ্যমে) সবগুলোরই দুর্দান্ত IDE সাপোর্ট আছে।
- অবশ্যই Common Lisp আর Scheme-এর জন্যও ভালো IDE আছে।
- সত্যিই পূর্ণাঙ্গ ফিচারসম্পন্ন Lisp চাইলে, Common Lisp, Clojure আর Racket সত্যিই বিস্তৃত
- কিছুটা ভিন্ন Lisp চাইলে, Clojure-এ একটি Lisp-এর জন্য বেশ অনন্য সিনট্যাক্স আছে।
- ম্যাক্রো আর মেটাপ্রোগ্রামিংয়ে আগ্রহ থাকলে, মূলত সবগুলোই ভালো বিকল্প! তবে নতুন ভাষা বানাতে চাইলে, বিশেষ করে Racket দুর্দান্ত
অবশ্যই, সময় থাকলে আমি সুপারিশ করব আপনি দু-একটি চেষ্টা করে দেখুন! আরও একটা কথা, বন্ধনী দেখে ভয় পাওয়ার কিছু নেই! আমি জানি আমি ভয় পেয়েছিলাম, আর সেজন্যই অনেক দিন Lisp শেখা পিছিয়ে রেখেছিলাম। তবে খুব দ্রুতই এগুলোর সঙ্গে অভ্যস্ত হয়ে যাবেন, আর হয়তো আমার মতো এগুলোকে ভালোবাসতেও শুরু করবেন। আসলে আমি এখন Lisp ভাষাগুলো খুব ভালোবাসি, এর সংক্ষিপ্ত সিনট্যাক্স, সহজ সিম্যান্টিকস, তবুও খুবই ভাবপ্রকাশী।