প্রোগ্রামিং ল্যাঙ্গুয়েজ

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

আমি যখন কলেজে পড়তাম, তখন কিউ-বেসিক (Q Basic) নামে একটা প্রোগ্রামিং ল্যাঙ্গুয়েজ শেখার ব্যর্থ চেষ্টা করেছিলাম। কিউ-বেসিক ল্যাঙ্গুয়েজটা আমাদের সিলেবাসে ছিল আর কী। এইচএসসি পরীক্ষার পরে কম্পিউটার কিনি, তখন এইচটিএমএল (HTML) শিখলাম কিছুটা, যদিও এটা ঠিক প্রোগ্রামিং ল্যাঙ্গুয়েজ না। তারপরে ২০০১ সালের শুরু থেকে সি (C) শেখা শুরু করি। আমাদের ভার্সিটির ক্লাস শুরু হয় ২০০১ সালের মে মাসে, আর ততদিনে সি এর বেসিক কিছুটা শেখা হয়েছে। আমি আমার বাকী ভার্সিটি-জীবন এর সুবিধা ভোগ করি। আমার যদি ভার্সিটির সি কোর্সের ক্লাশ থেকে সি শেখা লাগতো, তাহলে একটু অসুবিধাই হতো হয়ত, যেটা আমার অনেক ক্লাসমেটকে দেখে বুঝতে পেরেছি। সি শেখার সময় প্রথম বছরে ৩-৪টা বই কিনেছিলাম, যদিও সবগুলো বই শুরু থেকে শেষ পর্যন্ত পড়ি নাই। এক বছর সি শেখার পরে আমি হার্বার্ট শিল্ডের টিচ ইয়োরসেল্ফ সি প্লাস প্লাস বইটা পড়ি। কিন্তু এরপরে আর আমার সি প্লাস প্লাস (C++) চর্চা করা হয় নাই।

ভার্সিটির ফার্স্ট ইয়ারে একটা ছোট প্রজেক্ট করতে হয়েছিল, যেখানে এইচটিএমএল-এর পাশাপাশি একটু জাভাস্ক্রিপ্টও (Javascript) ব্যবহার করতে হয়েছিল। সেই ২০০২ সালের শুরুর দিকের ঘটনা। অল্প একটু জাভাস্ক্রিপ্ট শিখেছিলাম। আমার ইচ্ছা ছিল আমার এক বন্ধুকে দিয়ে প্রজেক্টটা করিয়ে ফেলবো। তো ব্যাটা রাত ২টার দিকে ঘুমিয়ে গেল, আমি চারটা পর্যন্ত অপেক্ষা করলাম। কারণ ওইদিনই প্রজেক্ট জমা দিতে হবে। চারটার পরে আমি আর কোনো উপায় না দেখে নিজেই কাজ করতে বসে গেলাম এবং শেষ পর্যন্ত কাজটা করেও ফেললাম। এরপরেও মাঝে মাঝে জাভাস্ক্রিপ্ট ব্যবহার করতে হয়েছিল, কিন্তু তেমন ভালোভাবে শেখা হয় নাই। আর গত চার-পাঁচ বছরে জাভাস্ক্রিপ্টে কিছুই করি নাই।

ভার্সিটির সেকেন্ড ইয়ারে অবজেক্ট ওরিয়েন্টেড কোর্স ছিল। সেই কোর্সে জাভা (Java) শিখি। আর তারপরের সেমিস্টারে একটা প্রজেক্টও করি জাভা ব্যবহার করে। তারপরে ২০০৬-২০০৭ সালে কিছু টুকটাক কাজ করতে জাভা ব্যবহার করেছিলাম।

সম্ভবত ফোর্থ ইয়ারে আমাদের মাইক্রোপ্রসেস কোর্স ছিল, সেই কোর্সের ল্যাবের জন্য এসেম্বলি ল্যাঙ্গুয়েজ (Assembly Language) শিখতে হয়েছিল।

আমার প্রথম প্রফেশনাল চাকরি ছিল টাইগার আইটি-তে, ২০০৭ সালের মাঝামাঝি। সেখানে আমি যেই প্রজেক্টে জয়েন করলাম, সেই প্রজেক্টে পার্ল (Perl) প্রোগ্রামিং ল্যাঙ্গুয়েজ ব্যবহার করতে হয়। কিন্তু আমি আগে কখনও এই ল্যাঙ্গুয়েজের নাম শুনি নাই। তাই বলে আমার কিন্তু চাকরি পেতে সমস্যা হয় নাই। কারণ ভালো কোম্পানীগুলো বেশি গুরুত্ব দেয় প্রবলেম সলভিং স্কিলের ওপর, প্রোগ্রামিং ল্যাঙ্গুয়েজ শেখার ওপর নয়।

আমার দ্বিতীয় সফটওয়্যার ইঞ্জিনিয়ারিং চাকরি ছিল ট্রিপার্ট ল্যাবসে (যেটা পরে প্লেডম কিনে নেয়, আবার প্লেডমকে ডিজনী কিনে নেয়)। সেখানে ব্যাকএন্ডের কাজ হতো পিএইচপি (PHP) প্রোগ্রামিং ল্যাঙ্গুয়েজে। আর মাঝেমধ্যে অল্পস্বল্প জাভাস্ক্রিপ্ট। তো সেই চাকরির ইন্টারভিউতে আমাকে জিজ্ঞাসা করল যে পিএইচপি পারি কী না। আমি সোজা বলে দিলাম যে পারি না, কারণ এর আগে ২-৩ দিন পিএইচপি নিয়ে গুতাগুতি করলেও সেটা বলার মতো কিছু না। কিন্তু সেজন্য আমার চাকরি পাওয়া আটকায় নাই। সেখানে এক বছর কাজ করার পরে একটা নতুন প্রজেক্টে কাজ করতে হয়, আর সেই প্রজেক্ট হচ্ছে অ্যাকশন স্ক্রিপ্ট (Actionscript)-এ। তো সেটাও দুই-তিন দিন শিখে কাজ শুরু করে দেই।

তারপরে তিন বছর আমার নিজের কোম্পানী মুক্তসফট নিয়ে ব্যস্ত ছিলাম। সেখানে পিএইচপি, পার্ল, পাইথন (Python) – এসব ল্যাঙ্গুয়েজ ব্যবহার করেছি, যখন প্রোগ্রামিং করতে হয়েছে। জেকুয়েরি ব্যবহার করেও একটা প্রজেক্ট করেছিলাম। আসলে ক্লায়েন্ট যেই ল্যাঙ্গুয়েজ চাইতো, সেটাই ব্যবহার করতাম। আর ক্লায়েন্ট কিছু না বললে পাইথন। তারপরে দুই বছর একটা আমেরিকান কোম্পানীর কাজ করি, সেখানে আমি পাইথন ব্যবহার করার সিদ্ধান্ত নেই, কারণ পাইথনে কোড করতে ভালো লাগে এবং সময় কম লাগে।

২০১৫ সালের মাঝামাঝি আমি সিঙ্গাপুরের গ্র্যাব নামক কোম্পানীতে ইন্টারভিউ দেই। বেশ কয়েকটা ইন্টারভিউ হয় এবং সেখানে আমি সি ব্যবহার করি, প্রবলেম সলভ করার জন্য। ইন্টারভিউ শেষে অফার পেয়ে জয়েন করি। জয়েন করার পরে জানতে পারলাম যে এখানে গো (Go বা Golang) ব্যবহার করা হয়, তাই প্রথম কিছুদিন গো শিখি। লক্ষ্য করার বিষয় হচ্ছে এত বড় কোম্পানী এত বেতন দিয়ে অন্য দেশ থেকে ইঞ্জিনিয়ার হায়ার করছে, ওরা কিন্তু এই বিষয় নিয়ে মাথা ঘামায় নাই যে আমি গো পারি কী না। সুতরাং বোঝাই যাচ্ছে যে কয়টা প্রোগ্রামিং ল্যাঙ্গুয়েজ পারি, এটা আসলে বিবেচ্য বিষয় নয়। কম্পিউটার সায়েন্সের বেসিক জ্ঞান (ডাটা স্ট্রাকচার, অ্যালগরিদম, অপারেটিং সিস্টেম, ডাটাবেজ, অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং, নেটওয়ার্কিং ইত্যাদি) এবং প্রবলেম সলভিং স্কিল-ই একজন ভালো সফটওয়্যার ইঞ্জিনিয়ার হওয়ার পূর্বশর্ত। আর কাজ করতে করতে সফটওয়্যার ইঞ্জিনিয়ারিংটাও শেখা হয়ে যায়, তবে তার জন্য ভালো কোম্পানীতে কাজ করাটা জরুরী।

বাইনারি সার্চ-এর কোড

আজকে সকালে গো (Go) প্রোগ্রামিং ল্যাঙ্গুয়েজে একটু কোডিং প্র্যাকটিস করার জন্য বাইনারি সার্চ ফাংশন লিখলাম, তারপরে ইউনিট টেস্ট লিখলাম (টেবল ড্রিভেন টেস্ট)। তো এমন সময় আমার মনে হলো লাইব্রেরি ফাংশনগুলো কিভাবে ইমপ্লিমেন্ট করা, সেটা দেখা দরকার। তো গো এর লাইব্রেরিতে যে বাইনারি সার্চ আছে, তার কোড (এবং ডকুমেন্টেশন) দেখে তো আমি মুগ্ধ!
এটা হচ্ছে গো-এর কোড:

func Search(n int, f func(int) bool) int {
    // Define f(-1) == false and f(n) == true.
    // Invariant: f(i-1) == false, f(j) == true.
    i, j := 0, n
    for i < j {
	h := i + (j-i)/2 // avoid overflow when computing h 
        if !f(h) { 
            i = h + 1 // preserves f(i-1) == false 
        } else { 
            j = h // preserves f(j) == true 
        } 
    } 
    return i
}

ওপরের কোডটুকু দেখলে আসলে পুরোপুরি বোঝা যাবে না কেন আমি এত মুগ্ধ। এই লিঙ্কে গেলে বিষয়টা আরো পরিষ্কার হবে: https://golang.org/src/sort/search.go। কোডের চেয়ে ডকুমেন্টেশন অনেক বেশি। আর এই বেশি ডকুমেন্টেশনসহ কোড হচ্ছে ১১৩ লাইন। কিন্তু বিষয় এখানেই শেষ নয়। আমার তারপরে চিন্তা আসল, আচ্ছা, এত সুন্দর কোড আর ডকুমেন্টেশন – এই কোডের টেস্ট কোড (ইউনিট টেস্ট) ওরা কিভাবে লিখল? তার জন্য চলে গেলাম এই লিঙ্কেঃ https://golang.org/src/sort/search_test.go। ১১৩ লাইনের search.go এর জন্য search_test.go তে আছে ১৬২ লাইন। এই দুইটা ফাইলের কোড এবং ডকুমেন্টেশন ঠিকমতো পড়লে শেখার আছে অনেক কিছুই।

তারপর চিন্তা করলাম, গো এর কোড এত সুন্দর, সি এর লাইব্রেরিতে এটা কিভাবে করা হয়েছে? গুগল সার্চ করে খুঁজে বের করলাম কোড।

void *
bsearch (register const void *key, const void *base0,
    size_t nmemb, register size_t size,
    register int (*compar)(const void *, const void *))
{
    register const char *base = (const char *) base0;
    register int lim, cmp;
    register const void *p;

    for (lim = nmemb; lim != 0; lim >>= 1) {
        p = base + (lim >> 1) * size;
        cmp = (*compar)(key, p);
        if (cmp == 0)
            return (void *)p;
        if (cmp > 0) {	/* key > p: move right */
            base = (const char *)p + size;
            lim--;
        } /* else move left */
    }
    return (NULL);
}

এই কোডটাও বেশ সুন্দর, গুছানো। ডকুমেন্টেশনও ভালো। আর পয়েন্টার দেখে ভয় পাওয়ার কারণ নাই (পয়েন্টার নিয়ে আমি কম্পিউটার প্রোগ্রামিং ২য় খণ্ড বইতে বিস্তারিত আলোচনা করেছি অনেক উদাহরণসহ)। তবে এখানে গিয়ে পুরো ফাইলটা না দেখলে এর মর্ম বোঝা যাবে না : https://github.com/gcc-mirror/gcc/blob/master/libiberty/bsearch.c

গো আর সি-এর কোড যেহেতু দেখলাম, পাইথনের কোডটাও দেখা যাক। তাই সেটাও সার্চ করে বের করে ফেললাম :

def bisect_left(a, x, lo=0, hi=None):
    """Return the index where to insert item x in list a, assuming a is sorted.

    The return value i is such that all e in a[:i] have e < x, and all e in a[i:] have e >= x.  So if x already appears in the list, a.insert(x) will
    insert just before the leftmost x already there.

    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """

    if lo < 0:
        raise ValueError('lo must be non-negative')
    if hi is None:
        hi = len(a)
    while lo < hi:
        mid = (lo+hi)//2
        if a[mid] < x: lo = mid+1
        else: hi = mid
    return lo

গো আর সি এর তুলনায় বেশ সহজ! তবে ডকুমেন্টেশন সংক্ষিপ্ত হলেও ভালো। এখানে গিয়ে পুরো কোড দেখা যাবে : https://github.com/python-git/python/blob/master/Lib/bisect.py

তারপরে ভাবলাম, আমার ব্লগের পাঠকদেরকে বিষয়টা জানানো যাক। আশা করি, বিশ্বমানের প্রোগ্রামারদের কোডের সঙ্গে পাঠকদের কিছুটা হলেও পরিচয় করিয়ে দিতে পেরেছি। কোডিং সঠিক হোক, কোড সুন্দর হোক।