सौ साल की भाषा
Originalअप्रैल 2003
(यह निबंध PyCon 2003 में आयोजित मुख्य भाषण से लिया गया है।)
यह अनुमान लगाना कठिन है कि सौ साल बाद जीवन कैसा होगा। ऐसी कुछ ही बातें हैं जो हम निश्चितता के साथ कह सकते हैं। हम जानते हैं कि हर कोई उड़ने वाली कारें चलाएगा, सैकड़ों मंजिल ऊंची इमारतों को अनुमति देने के लिए ज़ोनिंग कानूनों में ढील दी जाएगी, कि अधिकांश समय अंधेरा रहेगा, और सभी महिलाओं को मार्शल आर्ट का प्रशिक्षण दिया जाएगा। यहाँ मैं इस तस्वीर के एक विवरण पर ज़ूम इन करना चाहता हूँ। वे उन उड़ने वाली कारों को नियंत्रित करने वाले सॉफ़्टवेयर को लिखने के लिए किस तरह की प्रोग्रामिंग भाषा का उपयोग करेंगे?
इस पर विचार करना इसलिए महत्वपूर्ण नहीं है कि हम वास्तव में इन भाषाओं का प्रयोग करेंगे, बल्कि इसलिए कि यदि हम भाग्यशाली हुए तो इस बिंदु से उस बिंदु तक के मार्ग में हम इन भाषाओं का प्रयोग करेंगे।
मुझे लगता है कि प्रजातियों की तरह, भाषाएँ भी विकासवादी वृक्षों का निर्माण करेंगी, जिसमें सभी जगह मृत-अंत शाखाएँ होंगी। हम इसे पहले से ही होते हुए देख सकते हैं। कोबोल, अपनी सभी समय की लोकप्रियता के बावजूद, कोई बौद्धिक वंशज नहीं लगता है। यह एक विकासवादी मृत-अंत है - एक निएंडरथल भाषा।
मैं जावा के लिए भी इसी तरह के भाग्य की भविष्यवाणी करता हूं। लोग कभी-कभी मुझे मेल भेजते हैं, "आप कैसे कह सकते हैं कि जावा एक सफल भाषा नहीं बनेगी? यह पहले से ही एक सफल भाषा है।" और मैं मानता हूं कि यह है, अगर आप इस पर पुस्तकों द्वारा ली गई शेल्फ स्पेस (विशेष रूप से इस पर अलग-अलग किताबें) या उन स्नातक छात्रों की संख्या से सफलता को मापते हैं जो मानते हैं कि उन्हें नौकरी पाने के लिए इसे सीखना होगा। जब मैं कहता हूं कि जावा एक सफल भाषा नहीं बनेगी, तो मेरा मतलब कुछ और विशिष्ट है: कि जावा एक विकासवादी मृत-अंत बन जाएगी, जैसे कोबोल।
यह सिर्फ़ एक अनुमान है। मैं गलत भी हो सकता हूँ। यहाँ मेरा मुद्दा जावा का अपमान करना नहीं है, बल्कि विकासवादी वृक्षों के मुद्दे को उठाना है और लोगों को यह पूछने पर मजबूर करना है कि वृक्ष पर भाषा X कहाँ है? यह सवाल पूछने का कारण सिर्फ़ यह नहीं है कि हमारे भूत सौ साल बाद यह कह सकें कि मैंने तुमसे कहा था। ऐसा इसलिए है क्योंकि मुख्य शाखाओं के करीब रहना उन भाषाओं को खोजने के लिए एक उपयोगी अनुमान है जो अभी प्रोग्राम करने के लिए अच्छी होंगी।
किसी भी समय, आप शायद विकासवादी वृक्ष की मुख्य शाखाओं पर सबसे ज़्यादा खुश होते हैं। जब निएंडरथल की संख्या बहुत ज़्यादा थी, तब भी निएंडरथल होना बहुत बुरा रहा होगा। क्रो-मैग्नन लगातार आपके पास आते और आपको पीटते और आपका खाना चुराते रहते।
मैं यह जानना चाहता हूँ कि सौ साल बाद भाषाएँ कैसी होंगी, ताकि मैं जान सकूँ कि अभी पेड़ की किस शाखा पर दांव लगाना है।
भाषाओं का विकास प्रजातियों के विकास से अलग है क्योंकि शाखाएँ आपस में मिल सकती हैं। उदाहरण के लिए, फोरट्रान शाखा, अल्गोल के वंशजों के साथ विलीन होती हुई प्रतीत होती है। सिद्धांत रूप में यह प्रजातियों के लिए भी संभव है, लेकिन यह किसी कोशिका से बड़ी किसी भी चीज़ के साथ होने की संभावना नहीं है।
भाषाओं के लिए अभिसरण की संभावना अधिक होती है, आंशिक रूप से इसलिए क्योंकि संभावनाओं का दायरा छोटा होता है, और आंशिक रूप से इसलिए क्योंकि उत्परिवर्तन यादृच्छिक नहीं होते। भाषा डिजाइनर जानबूझकर अन्य भाषाओं के विचारों को शामिल करते हैं।
भाषा डिज़ाइनरों के लिए यह सोचना विशेष रूप से उपयोगी है कि प्रोग्रामिंग भाषाओं का विकास किस ओर ले जाएगा, क्योंकि वे उसी के अनुसार आगे बढ़ सकते हैं। उस स्थिति में, "मुख्य शाखा पर बने रहना" एक अच्छी भाषा चुनने के तरीके से कहीं अधिक हो जाता है। यह भाषा डिज़ाइन के बारे में सही निर्णय लेने के लिए एक अनुमान बन जाता है।
किसी भी प्रोग्रामिंग भाषा को दो भागों में विभाजित किया जा सकता है: कुछ मूलभूत ऑपरेटरों का समूह जो स्वयंसिद्धों की भूमिका निभाते हैं, तथा शेष भाषा, जिसे सिद्धांततः इन मूलभूत ऑपरेटरों के संदर्भ में लिखा जा सकता है।
मुझे लगता है कि किसी भाषा के दीर्घकालिक अस्तित्व में मूलभूत संचालक सबसे महत्वपूर्ण कारक हैं। बाकी आप बदल सकते हैं। यह उस नियम की तरह है कि घर खरीदते समय आपको सबसे पहले स्थान पर विचार करना चाहिए। बाकी सब कुछ आप बाद में ठीक कर सकते हैं, लेकिन आप स्थान को ठीक नहीं कर सकते।
मुझे लगता है कि यह महत्वपूर्ण है कि न केवल स्वयंसिद्धों को अच्छी तरह से चुना जाए, बल्कि यह भी कि उनमें से कुछ ही हों। गणितज्ञों ने हमेशा स्वयंसिद्धों के बारे में यही महसूस किया है-- जितने कम, उतना बेहतर-- और मुझे लगता है कि वे कुछ सही कह रहे हैं।
कम से कम, यह एक उपयोगी अभ्यास होना चाहिए ताकि किसी भाषा के मूल को करीब से देखा जा सके और यह देखा जा सके कि क्या कोई स्वयंसिद्ध बातें हैं जिन्हें हटाया जा सकता है। मैंने एक आलसी के रूप में अपने लंबे करियर में पाया है कि बेकार चीजें बेकार चीजें पैदा करती हैं, और मैंने इसे सॉफ्टवेयर के साथ-साथ बिस्तर के नीचे और कमरों के कोनों में भी होते देखा है।
मुझे लगता है कि विकासवादी वृक्ष की मुख्य शाखाएँ उन भाषाओं से होकर गुज़रती हैं जिनका कोर सबसे छोटा और साफ़ होता है। आप किसी भाषा के बारे में जितना ज़्यादा लिख सकते हैं, उतना ही बेहतर है।
बेशक, मैं यह पूछकर भी एक बड़ी धारणा बना रहा हूँ कि सौ साल बाद प्रोग्रामिंग भाषाएँ कैसी होंगी। क्या हम सौ साल बाद भी प्रोग्राम लिख पाएँगे? क्या हम कंप्यूटर को यह नहीं बताएँगे कि हम उनसे क्या करवाना चाहते हैं?
अभी तक इस विभाग में बहुत ज़्यादा प्रगति नहीं हुई है। मेरा अनुमान है कि सौ साल बाद भी लोग कंप्यूटर को बताएंगे कि उन्हें क्या करना है, इसके लिए वे प्रोग्राम का इस्तेमाल करेंगे जिन्हें हम इस तरह पहचानेंगे। हो सकता है कि कुछ ऐसे काम हों जिन्हें हम अभी प्रोग्राम लिखकर हल करते हैं और जिन्हें सौ साल बाद हल करने के लिए आपको प्रोग्राम लिखने की ज़रूरत नहीं होगी, लेकिन मुझे लगता है कि आज की तरह की प्रोग्रामिंग अभी भी काफ़ी होगी।
यह सोचना शायद बेतुका लगे कि कोई भी व्यक्ति यह भविष्यवाणी कर सकता है कि सौ साल बाद कोई भी तकनीक कैसी दिखेगी। लेकिन याद रखें कि हमारे पीछे पहले से ही लगभग पचास साल का इतिहास है। सौ साल आगे देखना एक समझ में आने वाला विचार है, जब हम इस बात पर विचार करते हैं कि पिछले पचास सालों में भाषाएँ कितनी धीमी गति से विकसित हुई हैं।
भाषाएँ धीरे-धीरे विकसित होती हैं क्योंकि वे वास्तव में तकनीक नहीं हैं। भाषाएँ संकेतन हैं। एक प्रोग्राम उस समस्या का औपचारिक विवरण है जिसे आप चाहते हैं कि कंप्यूटर आपके लिए हल करे। इसलिए प्रोग्रामिंग भाषाओं में विकास की दर परिवहन या संचार की तुलना में गणितीय संकेतन में विकास की दर की तरह है। गणितीय संकेतन विकसित होता है, लेकिन प्रौद्योगिकी में आप जो विशाल छलांग देखते हैं, उसके साथ नहीं।
सौ साल बाद कंप्यूटर चाहे जिस भी चीज से बने हों, यह अनुमान लगाना सुरक्षित लगता है कि वे अभी की तुलना में बहुत तेज़ होंगे। अगर मूर का नियम लागू होता रहा, तो वे 74 क्विंटिलियन (73,786,976,294,838,206,464) गुना तेज़ होंगे। यह कल्पना करना थोड़ा मुश्किल है। और वास्तव में, गति के मामले में सबसे संभावित भविष्यवाणी यह हो सकती है कि मूर का नियम काम करना बंद कर देगा। ऐसा कुछ भी जो हर अठारह महीने में दोगुना होने वाला हो, अंततः किसी तरह की मूलभूत सीमा से टकराने की संभावना है। लेकिन मुझे यह मानने में कोई परेशानी नहीं है कि कंप्यूटर बहुत तेज़ होंगे। भले ही वे केवल एक लाख गुना तेज़ हों, लेकिन इससे प्रोग्रामिंग भाषाओं के लिए आधारभूत नियम काफी हद तक बदल जाने चाहिए। अन्य बातों के अलावा, उन भाषाओं के लिए और जगह होगी जिन्हें अब धीमी भाषाएँ माना जाएगा, यानी ऐसी भाषाएँ जो बहुत कुशल कोड नहीं देती हैं।
और फिर भी कुछ अनुप्रयोगों को अभी भी गति की आवश्यकता होगी। कुछ समस्याएं जिन्हें हम कंप्यूटर से हल करना चाहते हैं, वे कंप्यूटर द्वारा बनाई गई हैं; उदाहरण के लिए, जिस दर पर आपको वीडियो छवियों को संसाधित करना है, वह इस बात पर निर्भर करता है कि कोई अन्य कंप्यूटर उन्हें किस दर पर उत्पन्न कर सकता है। और समस्याओं का एक और वर्ग है जिसमें स्वाभाविक रूप से चक्रों को अवशोषित करने की असीमित क्षमता होती है: छवि रेंडरिंग, क्रिप्टोग्राफी, सिमुलेशन।
यदि कुछ अनुप्रयोग लगातार अक्षम होते जा रहे हैं, जबकि अन्य हार्डवेयर द्वारा दी जा सकने वाली सभी गति की मांग करते रहते हैं, तो तेज़ कंप्यूटर का मतलब होगा कि भाषाओं को दक्षता की एक व्यापक श्रेणी को कवर करना होगा। हमने इसे पहले ही होते देखा है। पिछले दशकों के मानकों के अनुसार कुछ लोकप्रिय नई भाषाओं का वर्तमान कार्यान्वयन चौंकाने वाला अपव्ययी है।
ऐसा सिर्फ़ प्रोग्रामिंग भाषाओं के साथ ही नहीं होता। यह एक सामान्य ऐतिहासिक प्रवृत्ति है। जैसे-जैसे तकनीकें बेहतर होती जाती हैं, हर पीढ़ी ऐसी चीज़ें कर सकती है जिन्हें पिछली पीढ़ी बेकार समझती थी। तीस साल पहले लोग इस बात से हैरान होते कि हम कितनी सहजता से लंबी दूरी की फ़ोन कॉल करते हैं। सौ साल पहले लोग इस बात से और भी हैरान होते कि एक दिन एक पैकेज बोस्टन से मेम्फिस के ज़रिए न्यूयॉर्क पहुँच जाएगा।
मैं आपको पहले ही बता सकता हूँ कि अगले सौ सालों में तेज़ हार्डवेयर द्वारा हमें दिए जाने वाले उन सभी अतिरिक्त चक्रों का क्या होगा। वे लगभग सभी बर्बाद हो जाएँगे।
मैंने प्रोग्रामिंग तब सीखी जब कंप्यूटर की शक्ति कम थी। मुझे याद है कि मैंने अपने बेसिक प्रोग्राम से सभी स्पेस निकाल दिए थे ताकि वे 4K TRS-80 की मेमोरी में फिट हो जाएँ। यह सब बेहद अक्षम सॉफ़्टवेयर एक ही काम को बार-बार करके साइकिल चला रहा है, यह सोचना मुझे बहुत घिनौना लगता है। लेकिन मुझे लगता है कि यहाँ मेरी अंतर्ज्ञान गलत है। मैं एक ऐसे व्यक्ति की तरह हूँ जो गरीब परिवार में पला-बढ़ा हूँ और डॉक्टर के पास जाने जैसी महत्वपूर्ण चीज़ के लिए भी पैसे खर्च नहीं कर सकता।
कुछ तरह के कचरे वाकई घिनौने होते हैं। उदाहरण के लिए, एसयूवी यकीनन घिनौने होते, भले ही वे ऐसे ईंधन पर चलते हों जो कभी खत्म न हो और प्रदूषण न फैलाता हो। एसयूवी घिनौने होते हैं क्योंकि वे एक गंभीर समस्या का समाधान हैं। (मिनीवैन को ज़्यादा मर्दाना कैसे बनाया जाए।) लेकिन सभी तरह के कचरे बुरे नहीं होते। अब जब हमारे पास इसे सपोर्ट करने के लिए बुनियादी ढांचा है, तो आपकी लंबी दूरी की कॉल के मिनटों की गिनती करना मुश्किल लगने लगा है। अगर आपके पास संसाधन हैं, तो सभी फोन कॉल को एक तरह की चीज़ के रूप में सोचना ज़्यादा सुंदर है, चाहे दूसरा व्यक्ति कहीं भी हो।
अच्छा अपशिष्ट और बुरा अपशिष्ट होता है। मुझे अच्छे अपशिष्ट में दिलचस्पी है - वह अपशिष्ट जिसमें अधिक खर्च करके हम सरल डिजाइन प्राप्त कर सकते हैं। हम नए, तेज़ हार्डवेयर से मिलने वाले अपशिष्ट चक्रों के अवसरों का लाभ कैसे उठाएँगे?
गति की चाहत हमारे अंदर इतनी गहराई से समाई हुई है, हमारे छोटे से कंप्यूटर के साथ, कि इसे दूर करने के लिए सचेत प्रयास की आवश्यकता होगी। भाषा डिजाइन में, हमें सचेत रूप से ऐसी स्थितियों की तलाश करनी चाहिए जहाँ हम सुविधा में थोड़ी सी भी वृद्धि के लिए दक्षता का व्यापार कर सकें।
अधिकांश डेटा संरचनाएँ गति के कारण मौजूद हैं। उदाहरण के लिए, आज कई भाषाओं में स्ट्रिंग और सूचियाँ दोनों हैं। अर्थगत रूप से, स्ट्रिंग कमोबेश सूचियों का एक उपसमूह है जिसमें तत्व वर्ण होते हैं। तो आपको एक अलग डेटा प्रकार की आवश्यकता क्यों है? वास्तव में, आपको इसकी आवश्यकता नहीं है। स्ट्रिंग केवल दक्षता के लिए मौजूद हैं। लेकिन प्रोग्राम को तेज़ चलाने के लिए हैक के साथ भाषा के अर्थ को अव्यवस्थित करना बेकार है। किसी भाषा में स्ट्रिंग का होना समय से पहले अनुकूलन का मामला लगता है।
अगर हम किसी भाषा के मूल को स्वयंसिद्धों के एक समूह के रूप में सोचते हैं, तो निश्चित रूप से अतिरिक्त स्वयंसिद्धों का होना घृणित है जो केवल दक्षता के लिए कोई अभिव्यंजक शक्ति नहीं जोड़ते हैं। दक्षता महत्वपूर्ण है, लेकिन मुझे नहीं लगता कि इसे प्राप्त करने का यह सही तरीका है।
मुझे लगता है कि इस समस्या को हल करने का सही तरीका प्रोग्राम के अर्थ को कार्यान्वयन विवरण से अलग करना है। लिस्ट और स्ट्रिंग दोनों रखने के बजाय, सिर्फ़ लिस्ट रखें, साथ ही कंपाइलर को ऑप्टिमाइज़ेशन सलाह देने का कोई तरीका भी रखें, जिससे ज़रूरत पड़ने पर स्ट्रिंग को निरंतर बाइट्स के रूप में रखा जा सके।
चूँकि अधिकांश प्रोग्राम में गति मायने नहीं रखती, इसलिए आपको आमतौर पर इस तरह के माइक्रोमैनेजमेंट की ज़रूरत नहीं होगी। जैसे-जैसे कंप्यूटर तेज़ होते जाएँगे, यह बात और भी सच होती जाएगी।
कार्यान्वयन के बारे में कम कहने से कार्यक्रम अधिक लचीले बनेंगे। कार्यक्रम लिखते समय विनिर्देश बदलते रहते हैं, और यह न केवल अपरिहार्य है, बल्कि वांछनीय भी है।
"निबंध" शब्द फ्रेंच क्रिया "निबंधक" से आया है, जिसका अर्थ है "कोशिश करना"। मूल अर्थ में, निबंध वह होता है जिसे आप किसी बात को समझने की कोशिश करने के लिए लिखते हैं। सॉफ्टवेयर में भी ऐसा होता है। मुझे लगता है कि कुछ बेहतरीन प्रोग्राम निबंध थे, इस अर्थ में कि लेखकों को यह नहीं पता था कि वे क्या लिखना शुरू कर रहे हैं।
लिस्प हैकर्स को पहले से ही डेटा संरचनाओं के साथ लचीले होने के महत्व के बारे में पता है। हम प्रोग्राम का पहला संस्करण इस तरह लिखते हैं कि यह सूचियों के साथ सब कुछ करता है। ये शुरुआती संस्करण इतने चौंकाने वाले अकुशल हो सकते हैं कि उन्हें यह सोचने के लिए सचेत प्रयास की आवश्यकता होती है कि वे क्या कर रहे हैं, ठीक वैसे ही जैसे, कम से कम मेरे लिए, स्टेक खाने के लिए सचेत प्रयास की आवश्यकता होती है कि यह न सोचें कि यह कहाँ से आया है।
सौ साल बाद प्रोग्रामर सबसे ज़्यादा ऐसी भाषा की तलाश करेंगे जिसमें आप कम से कम प्रयास में किसी प्रोग्राम का अविश्वसनीय रूप से अक्षम संस्करण 1 बना सकें। कम से कम, आज के समय में हम इसे इसी तरह से परिभाषित करेंगे। वे यही कहेंगे कि उन्हें ऐसी भाषा चाहिए जिसमें प्रोग्राम करना आसान हो।
अकुशल सॉफ़्टवेयर घिनौना नहीं है। घिनौना वह भाषा है जो प्रोग्रामर को अनावश्यक काम करने पर मजबूर करती है। प्रोग्रामर का समय बर्बाद करना असली अकुशलता है, मशीन का समय बर्बाद करना नहीं। जैसे-जैसे कंप्यूटर तेज़ होते जाएंगे, यह बात और भी स्पष्ट होती जाएगी।
मुझे लगता है कि स्ट्रिंग्स से छुटकारा पाना पहले से ही कुछ ऐसा है जिसके बारे में हम सोच सकते हैं। हमने इसे आर्क में किया, और यह एक जीत प्रतीत होती है; कुछ ऑपरेशन जिन्हें नियमित अभिव्यक्तियों के रूप में वर्णित करना अजीब होगा, उन्हें आसानी से पुनरावर्ती कार्यों के रूप में वर्णित किया जा सकता है।
डेटा संरचनाओं का यह समतलीकरण किस हद तक जाएगा? मैं ऐसी संभावनाओं के बारे में सोच सकता हूँ जो मेरे विवेकपूर्ण व्यापक दिमाग के साथ मुझे भी चौंका सकती हैं। क्या हम उदाहरण के लिए, सरणियों से छुटकारा पा लेंगे? आखिरकार, वे हैश टेबल का एक उपसमूह मात्र हैं जहाँ कुंजियाँ पूर्णांकों के सदिश हैं। क्या हम हैश टेबल को सूचियों से बदल देंगे?
इससे भी ज़्यादा चौंकाने वाली संभावनाएँ हैं। उदाहरण के लिए, 1960 में मैकार्थी ने जिस लिस्प का वर्णन किया था, उसमें संख्याएँ नहीं थीं। तार्किक रूप से, आपको संख्याओं की अलग से अवधारणा रखने की ज़रूरत नहीं है, क्योंकि आप उन्हें सूचियों के रूप में दर्शा सकते हैं: पूर्णांक n को n तत्वों की सूची के रूप में दर्शाया जा सकता है। आप इस तरह से गणित कर सकते हैं। यह असहनीय रूप से अक्षम है।
किसी ने भी व्यवहार में संख्याओं को सूचियों के रूप में लागू करने का प्रस्ताव नहीं रखा। वास्तव में, मैकार्थी के 1960 के पेपर को उस समय लागू करने का इरादा नहीं था। यह एक सैद्धांतिक अभ्यास था, ट्यूरिंग मशीन के लिए एक अधिक सुंदर विकल्प बनाने का प्रयास। जब किसी ने, अप्रत्याशित रूप से, इस पेपर को लिया और इसे एक कार्यशील लिस्प इंटरप्रेटर में अनुवादित किया, तो निश्चित रूप से संख्याओं को सूचियों के रूप में नहीं दर्शाया गया था; उन्हें बाइनरी में दर्शाया गया था, जैसा कि हर दूसरी भाषा में होता है।
क्या कोई प्रोग्रामिंग भाषा मूलभूत डेटा प्रकार के रूप में संख्याओं से छुटकारा पाने की हद तक जा सकती है? मैं यह सवाल गंभीर सवाल के रूप में नहीं बल्कि भविष्य के साथ खेलने के तरीके के रूप में पूछ रहा हूँ। यह एक अप्रतिरोध्य बल और एक अचल वस्तु के बीच टकराव के काल्पनिक मामले की तरह है - यहाँ, एक अकल्पनीय रूप से अक्षम कार्यान्वयन अकल्पनीय रूप से महान संसाधनों से मिलता है। मुझे नहीं लगता कि ऐसा क्यों नहीं हो सकता। भविष्य बहुत लंबा है। अगर हम मूल भाषा में स्वयंसिद्धों की संख्या को कम करने के लिए कुछ कर सकते हैं, तो ऐसा लगता है कि यह अनंत के करीब पहुँचने पर दांव लगाने का पक्ष होगा। अगर यह विचार सौ साल बाद भी असहनीय लगता है, तो शायद यह हज़ार साल बाद भी असहनीय न हो।
इस बारे में स्पष्ट होने के लिए, मैं यह प्रस्ताव नहीं कर रहा हूँ कि सभी संख्यात्मक गणनाएँ वास्तव में सूचियों का उपयोग करके की जाएँगी। मैं यह प्रस्ताव कर रहा हूँ कि कार्यान्वयन के बारे में किसी भी अतिरिक्त संकेतन से पहले, मूल भाषा को इस तरह से परिभाषित किया जाना चाहिए। व्यवहार में कोई भी प्रोग्राम जो किसी भी मात्रा में गणित करना चाहता है, वह संभवतः संख्याओं को बाइनरी में दर्शाएगा, लेकिन यह एक अनुकूलन होगा, मूल भाषा शब्दार्थ का हिस्सा नहीं।
चक्रों को जलाने का एक और तरीका है कि एप्लिकेशन और हार्डवेयर के बीच सॉफ़्टवेयर की कई परतें हों। यह भी एक प्रवृत्ति है जिसे हम पहले से ही देख रहे हैं: कई हालिया भाषाओं को बाइट कोड में संकलित किया जाता है। बिल वुड्स ने एक बार मुझसे कहा था कि, एक सामान्य नियम के रूप में, व्याख्या की प्रत्येक परत की गति में 10 गुना की लागत आती है। यह अतिरिक्त लागत आपको लचीलापन खरीदती है।
आर्क का सबसे पहला संस्करण इस तरह के बहु-स्तरीय धीमेपन का एक चरम मामला था, जिसके अनुरूप लाभ भी थे। यह कॉमन लिस्प के शीर्ष पर लिखा गया एक क्लासिक "मेटासर्कुलर" इंटरप्रेटर था, जिसमें मैकार्थी के मूल लिस्प पेपर में परिभाषित इवल फ़ंक्शन के साथ एक निश्चित पारिवारिक समानता थी। पूरी चीज़ कोड की केवल दो सौ पंक्तियों की थी, इसलिए इसे समझना और बदलना बहुत आसान था। हमने जिस कॉमन लिस्प का इस्तेमाल किया, CLisp, वह खुद एक बाइट कोड इंटरप्रेटर के शीर्ष पर चलता है। इसलिए यहाँ हमारे पास व्याख्या के दो स्तर थे, उनमें से एक (शीर्ष वाला) चौंकाने वाला अक्षम था, और भाषा प्रयोग करने योग्य थी। मुश्किल से प्रयोग करने योग्य, मैं मानता हूँ, लेकिन प्रयोग करने योग्य।
सॉफ्टवेयर को कई परतों के रूप में लिखना अनुप्रयोगों के भीतर भी एक शक्तिशाली तकनीक है। बॉटम-अप प्रोग्रामिंग का अर्थ है एक प्रोग्राम को परतों की एक श्रृंखला के रूप में लिखना, जिनमें से प्रत्येक ऊपर वाले के लिए एक भाषा के रूप में कार्य करता है। यह दृष्टिकोण छोटे, अधिक लचीले प्रोग्राम उत्पन्न करता है। यह उस पवित्र कब्र, पुन: प्रयोज्यता के लिए सबसे अच्छा मार्ग भी है। एक भाषा परिभाषा के अनुसार पुन: प्रयोज्य है। आप अपने एप्लिकेशन के जितने अधिक भाग को उस प्रकार के एप्लिकेशन को लिखने के लिए भाषा में डाल सकते हैं, आपका सॉफ़्टवेयर उतना ही अधिक पुन: प्रयोज्य होगा।
किसी तरह 1980 के दशक में ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में पुन: प्रयोज्यता का विचार जुड़ गया, और इसके विपरीत कोई भी सबूत इसे मुक्त करने में सक्षम नहीं लगता है। लेकिन हालांकि कुछ ऑब्जेक्ट-ओरिएंटेड सॉफ़्टवेयर पुन: प्रयोज्य हैं, लेकिन जो चीज़ उन्हें पुन: प्रयोज्य बनाती है वह है उनका नीचे से ऊपर तक होना, न कि उनका ऑब्जेक्ट-ओरिएंटेड होना। लाइब्रेरीज़ पर विचार करें: वे पुन: प्रयोज्य हैं क्योंकि वे भाषा हैं, चाहे वे ऑब्जेक्ट-ओरिएंटेड शैली में लिखी गई हों या नहीं।
वैसे, मैं ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के खत्म होने की भविष्यवाणी नहीं करता। हालाँकि मुझे नहीं लगता कि यह अच्छे प्रोग्रामर को कुछ खास दे सकता है, सिवाय कुछ खास डोमेन के, यह बड़े संगठनों के लिए अनूठा है। ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग स्पेगेटी कोड लिखने का एक स्थायी तरीका प्रदान करता है। यह आपको पैच की एक श्रृंखला के रूप में प्रोग्राम को एकत्रित करने देता है।
बड़े संगठन हमेशा इसी तरीके से सॉफ्टवेयर विकसित करते हैं, और मुझे उम्मीद है कि सौ साल बाद भी यह बात उतनी ही सच होगी जितनी आज है।
जब तक हम भविष्य के बारे में बात कर रहे हैं, हमें समानांतर संगणना के बारे में बात करनी चाहिए, क्योंकि यही वह जगह है जहाँ यह विचार जीवित है। यानी, आप जब भी बात कर रहे हों, समानांतर संगणना ऐसी चीज़ लगती है जो भविष्य में होने वाली है।
क्या भविष्य कभी भी इसे पकड़ पाएगा? लोग कम से कम 20 वर्षों से समानांतर संगणना के बारे में बात कर रहे हैं, और इसने अब तक प्रोग्रामिंग अभ्यास को बहुत प्रभावित नहीं किया है। या नहीं? चिप डिजाइनरों को पहले से ही इसके बारे में सोचना होगा, और इसलिए लोगों को मल्टी-सीपीयू कंप्यूटर पर सिस्टम सॉफ़्टवेयर लिखने की कोशिश करनी होगी।
असली सवाल यह है कि अमूर्तता की सीढ़ी पर समानांतरता कितनी दूर तक जाएगी? क्या सौ साल बाद यह एप्लीकेशन प्रोग्रामर को भी प्रभावित करेगा? या यह कुछ ऐसा होगा जिसके बारे में कंपाइलर लेखक सोचते हैं, लेकिन जो आमतौर पर एप्लीकेशन के सोर्स कोड में अदृश्य होता है?
एक बात जो संभव लगती है वह यह है कि समानांतरता के अधिकांश अवसर बर्बाद हो जाएँगे। यह मेरे अधिक सामान्य पूर्वानुमान का एक विशेष मामला है कि हमें दी गई अधिकांश अतिरिक्त कंप्यूटर शक्ति बर्बाद हो जाएगी। मुझे उम्मीद है कि अंतर्निहित हार्डवेयर की शानदार गति के साथ, समानांतरता कुछ ऐसी चीज होगी जो स्पष्ट रूप से पूछे जाने पर उपलब्ध होगी, लेकिन आमतौर पर इसका उपयोग नहीं किया जाएगा। इसका तात्पर्य यह है कि सौ वर्षों में हमारे पास जिस तरह की समानांतरता होगी, वह विशेष अनुप्रयोगों को छोड़कर, व्यापक समानांतरता नहीं होगी। मुझे उम्मीद है कि सामान्य प्रोग्रामर के लिए यह उन प्रक्रियाओं को अलग करने में सक्षम होने जैसा होगा जो सभी समानांतर रूप से चलती हैं।
और यह, डेटा संरचनाओं के विशिष्ट कार्यान्वयन के लिए पूछने जैसा होगा, ऐसा कुछ होगा जो आप प्रोग्राम के जीवन में काफी देर से करते हैं, जब आप इसे अनुकूलित करने का प्रयास करते हैं। संस्करण 1s आम तौर पर समानांतर गणना से प्राप्त होने वाले किसी भी लाभ को अनदेखा कर देगा, ठीक उसी तरह जैसे वे डेटा के विशिष्ट प्रतिनिधित्व से प्राप्त होने वाले लाभों को अनदेखा कर देंगे।
विशेष प्रकार के अनुप्रयोगों को छोड़कर, सौ वर्षों में लिखे जाने वाले कार्यक्रमों में समांतरता व्याप्त नहीं होगी। अगर ऐसा हुआ तो यह समय से पहले का अनुकूलन होगा।
सौ साल में कितनी प्रोग्रामिंग भाषाएँ होंगी? हाल ही में बहुत सी नई प्रोग्रामिंग भाषाएँ सामने आई हैं। इसका एक कारण यह भी है कि तेज़ हार्डवेयर ने प्रोग्रामर को एप्लिकेशन के आधार पर गति और सुविधा के बीच अलग-अलग समझौते करने की अनुमति दी है। अगर यह एक वास्तविक प्रवृत्ति है, तो सौ साल में हमारे पास जो हार्डवेयर होगा, वह इसे और बढ़ा देगा।
और फिर भी सौ साल में शायद कुछ ही व्यापक रूप से इस्तेमाल की जाने वाली भाषाएँ होंगी। मेरे ऐसा कहने का एक कारण आशावाद है: ऐसा लगता है कि, अगर आपने वाकई अच्छा काम किया, तो आप एक ऐसी भाषा बना सकते हैं जो धीमे संस्करण 1 को लिखने के लिए आदर्श हो, और फिर भी कंपाइलर को सही अनुकूलन सलाह के साथ, ज़रूरत पड़ने पर बहुत तेज़ कोड भी दे। इसलिए, चूँकि मैं आशावादी हूँ, इसलिए मैं भविष्यवाणी करने जा रहा हूँ कि स्वीकार्य और अधिकतम दक्षता के बीच बहुत बड़े अंतर के बावजूद, सौ साल में प्रोग्रामर के पास ऐसी भाषाएँ होंगी जो इसका ज़्यादातर हिस्सा कवर कर सकेंगी।
जैसे-जैसे यह अंतर बढ़ता जाएगा, प्रोफाइलर का महत्व बढ़ता जाएगा। प्रोफाइलिंग पर अब कम ध्यान दिया जाता है। बहुत से लोग अभी भी मानते हैं कि तेज़ एप्लिकेशन प्राप्त करने का तरीका ऐसे कंपाइलर लिखना है जो तेज़ कोड उत्पन्न करते हैं। जैसे-जैसे स्वीकार्य और अधिकतम प्रदर्शन के बीच का अंतर बढ़ता जाएगा, यह स्पष्ट होता जाएगा कि तेज़ एप्लिकेशन प्राप्त करने का तरीका एक से दूसरे तक एक अच्छा मार्गदर्शक होना है।
जब मैं कहता हूँ कि शायद केवल कुछ ही भाषाएँ होंगी, तो मेरा मतलब डोमेन-विशिष्ट "छोटी भाषाओं" से नहीं है। मुझे लगता है कि ऐसी एम्बेडेड भाषाएँ एक बढ़िया विचार हैं, और मुझे उम्मीद है कि वे बहुत ज़्यादा बढ़ेंगी। लेकिन मुझे उम्मीद है कि उन्हें इतनी पतली परत में लिखा जाएगा कि उपयोगकर्ता उनके नीचे सामान्य-उद्देश्य वाली भाषा को देख सकें।
भविष्य की भाषाओं को कौन डिजाइन करेगा? पिछले दस सालों में सबसे रोमांचक रुझानों में से एक है पर्ल, पायथन और रूबी जैसी ओपन-सोर्स भाषाओं का उदय। भाषा डिजाइन पर हैकर्स का कब्ज़ा हो रहा है। अब तक के नतीजे गड़बड़ हैं, लेकिन उत्साहजनक हैं। उदाहरण के लिए, पर्ल में कुछ आश्चर्यजनक रूप से नए विचार हैं। कई आश्चर्यजनक रूप से खराब हैं, लेकिन महत्वाकांक्षी प्रयासों के लिए यह हमेशा सच होता है। उत्परिवर्तन की वर्तमान दर पर, भगवान ही जानता है कि सौ साल में पर्ल क्या विकसित हो सकता है।
यह सच नहीं है कि जो लोग कुछ नहीं कर सकते, वे पढ़ाते हैं (मेरे जानने वाले कुछ बेहतरीन हैकर प्रोफेसर हैं), लेकिन यह सच है कि बहुत सी ऐसी चीजें हैं जो पढ़ाने वाले नहीं कर सकते। शोध जातिगत प्रतिबंध लगाता है। किसी भी अकादमिक क्षेत्र में ऐसे विषय होते हैं जिन पर काम करना ठीक है और कुछ ऐसे होते हैं जिन पर काम करना ठीक नहीं है। दुर्भाग्य से स्वीकार्य और निषिद्ध विषयों के बीच का अंतर आमतौर पर इस बात पर आधारित होता है कि शोध पत्रों में वर्णित कार्य कितना बौद्धिक लगता है, बजाय इसके कि यह अच्छे परिणाम प्राप्त करने के लिए कितना महत्वपूर्ण है। चरम मामला शायद साहित्य है; साहित्य का अध्ययन करने वाले लोग शायद ही कभी ऐसा कुछ कहते हैं जो इसे बनाने वालों के लिए थोड़ा भी उपयोगी हो।
हालाँकि विज्ञान के क्षेत्र में स्थिति बेहतर है, लेकिन आपको जिस तरह के काम करने की अनुमति है और जिस तरह के काम से अच्छी भाषाएँ बनती हैं, उनके बीच ओवरलैप बहुत कम है। (ओलिन शिवर्स ने इस बारे में बहुत ही शानदार तरीके से शिकायत की है।) उदाहरण के लिए, टाइप्स शोध पत्रों का एक अटूट स्रोत प्रतीत होते हैं, इस तथ्य के बावजूद कि स्थिर टाइपिंग सच्चे मैक्रोज़ को रोकती है - जिसके बिना, मेरी राय में, कोई भी भाषा उपयोग करने लायक नहीं है।
यह प्रवृत्ति केवल "शोध" के बजाय ओपन-सोर्स परियोजनाओं के रूप में विकसित की जाने वाली भाषाओं की ओर नहीं है, बल्कि उन एप्लीकेशन प्रोग्रामर्स द्वारा भाषाओं को डिज़ाइन करने की ओर है, जिन्हें उनका उपयोग करने की आवश्यकता है, न कि कंपाइलर लेखकों द्वारा। यह एक अच्छा रुझान लगता है और मुझे उम्मीद है कि यह जारी रहेगा।
सौ वर्षों बाद की भौतिकी के विपरीत, जिसके बारे में भविष्यवाणी करना लगभग असंभव है, मैं समझता हूं कि सैद्धांतिक रूप से अब ऐसी भाषा का डिजाइन तैयार करना संभव हो सकता है जो सौ वर्षों बाद उपयोगकर्ताओं को आकर्षित कर सके।
भाषा को डिज़ाइन करने का एक तरीका यह है कि आप जिस प्रोग्राम को लिखना चाहते हैं, उसे लिख लें, भले ही कोई कंपाइलर हो जो उसका अनुवाद कर सके या कोई हार्डवेयर हो जो उसे चला सके। जब आप ऐसा करते हैं तो आप असीमित संसाधनों की कल्पना कर सकते हैं। ऐसा लगता है कि हमें आज के साथ-साथ सौ साल बाद भी असीमित संसाधनों की कल्पना करने में सक्षम होना चाहिए।
कोई व्यक्ति कौन सा प्रोग्राम लिखना चाहेगा? जो भी कम से कम काम हो। सिवाय इसके कि: जो भी कम से कम काम हो अगर प्रोग्रामिंग के बारे में आपके विचार पहले से ही उन भाषाओं से प्रभावित न हों जिनका आप वर्तमान में उपयोग कर रहे हैं। ऐसा प्रभाव इतना व्यापक हो सकता है कि इसे दूर करने के लिए बहुत प्रयास करना पड़ता है। आपको लगता होगा कि हम जैसे आलसी प्राणियों के लिए यह स्पष्ट होगा कि कम से कम प्रयास के साथ प्रोग्राम को कैसे व्यक्त किया जाए। वास्तव में, जो संभव है उसके बारे में हमारे विचार आमतौर पर उस भाषा तक सीमित होते हैं जिसमें हम सोचते हैं कि प्रोग्राम के आसान फॉर्मूलेशन बहुत आश्चर्यजनक लगते हैं। वे ऐसी चीजें हैं जिन्हें आपको खोजना है, न कि ऐसी चीजें जो आप स्वाभाविक रूप से अपनाते हैं।
यहाँ एक मददगार तरकीब यह है कि प्रोग्राम की लंबाई को इस बात के अनुमान के तौर पर इस्तेमाल किया जाए कि इसे लिखने में कितना काम है। बेशक, अक्षरों की लंबाई नहीं, बल्कि अलग-अलग वाक्यविन्यास तत्वों की लंबाई - मूल रूप से, पार्स ट्री का आकार। यह पूरी तरह सच नहीं हो सकता है कि सबसे छोटा प्रोग्राम लिखने में सबसे कम काम है, लेकिन यह इतना करीब है कि आप कम से कम काम वाले अस्पष्ट, नज़दीकी प्रोग्राम की तुलना में संक्षिप्तता के ठोस लक्ष्य को पाने के लिए बेहतर हैं। फिर भाषा डिजाइन के लिए एल्गोरिदम बन जाता है: एक प्रोग्राम को देखें और पूछें, क्या इसे लिखने का कोई ऐसा तरीका है जो छोटा हो?
व्यवहार में, एक काल्पनिक सौ साल की भाषा में प्रोग्राम लिखना अलग-अलग डिग्री पर काम करेगा, यह इस बात पर निर्भर करता है कि आप कोर के कितने करीब हैं। सॉर्ट रूटीन जो आप अभी लिख सकते हैं। लेकिन अभी यह अनुमान लगाना मुश्किल होगा कि सौ साल में किस तरह की लाइब्रेरी की जरूरत होगी। संभवतः कई लाइब्रेरी ऐसे डोमेन के लिए होंगी जो अभी तक अस्तित्व में भी नहीं हैं। उदाहरण के लिए, अगर SETI@home काम करता है, तो हमें एलियंस के साथ संवाद करने के लिए लाइब्रेरी की आवश्यकता होगी। जब तक कि वे इतने उन्नत न हों कि वे पहले से ही XML में संवाद कर सकें।
दूसरी ओर, मुझे लगता है कि आप आज ही कोर भाषा को डिज़ाइन करने में सक्षम हो सकते हैं। वास्तव में, कुछ लोग तर्क दे सकते हैं कि यह 1958 में ही डिज़ाइन हो चुकी थी।
अगर सौ साल पुरानी भाषा आज उपलब्ध होती, तो क्या हम उसमें प्रोग्राम करना चाहते? इस सवाल का जवाब देने का एक तरीका यह है कि हम पीछे देखें। अगर आज की प्रोग्रामिंग भाषाएँ 1960 में उपलब्ध होतीं, तो क्या कोई उनका इस्तेमाल करना चाहता?
कुछ मायनों में, इसका उत्तर है नहीं। आज की भाषाएँ ऐसी अवसंरचना मानती हैं जो 1960 में मौजूद नहीं थी। उदाहरण के लिए, पायथन जैसी कोई भाषा जिसमें इंडेंटेशन महत्वपूर्ण है, प्रिंटर टर्मिनल पर बहुत अच्छी तरह से काम नहीं करेगी। लेकिन ऐसी समस्याओं को एक तरफ रखते हुए - उदाहरण के लिए, यह मानते हुए कि सभी प्रोग्राम सिर्फ़ कागज़ पर लिखे गए थे - क्या 1960 के दशक के प्रोग्रामर उन भाषाओं में प्रोग्राम लिखना पसंद करते जो हम आज इस्तेमाल करते हैं?
मुझे ऐसा लगता है। कुछ कम कल्पनाशील लोगों को, जिनके पास प्रोग्राम के बारे में उनके विचारों में प्रारंभिक भाषाओं की कलाकृतियाँ थीं, परेशानी हो सकती थी। (आप पॉइंटर अंकगणित किए बिना डेटा में हेरफेर कैसे कर सकते हैं? आप गोटो के बिना फ्लो चार्ट कैसे लागू कर सकते हैं?) लेकिन मुझे लगता है कि सबसे चतुर प्रोग्रामर को वर्तमान समय की भाषाओं का अधिकतम उपयोग करने में कोई परेशानी नहीं होती, अगर उनके पास वे होतीं।
अगर हमारे पास अभी सौ साल पुरानी भाषा होती, तो यह कम से कम एक बेहतरीन छद्म कोड तो बनाती। सॉफ्टवेयर लिखने के लिए इसका इस्तेमाल करने के बारे में क्या ख्याल है? चूँकि सौ साल पुरानी भाषा को कुछ अनुप्रयोगों के लिए तेज़ कोड बनाने की ज़रूरत होगी, इसलिए संभवतः यह हमारे हार्डवेयर पर स्वीकार्य रूप से अच्छी तरह से चलने के लिए पर्याप्त कुशल कोड बना सकती है। हमें सौ साल बाद उपयोगकर्ताओं की तुलना में अधिक अनुकूलन सलाह देनी पड़ सकती है, लेकिन फिर भी यह एक शुद्ध जीत हो सकती है।
अब हमारे पास दो विचार हैं, जिन्हें अगर आप मिला दें, तो दिलचस्प संभावनाएँ सामने आती हैं: (1) सौ साल की भाषा, सिद्धांत रूप में, आज डिज़ाइन की जा सकती है, और (2) ऐसी भाषा, अगर मौजूद है, तो आज प्रोग्राम करने के लिए अच्छी हो सकती है। जब आप इन विचारों को इस तरह से देखते हैं, तो यह सोचना मुश्किल नहीं है कि सौ साल की भाषा को अभी लिखने की कोशिश क्यों न की जाए?
जब आप भाषा डिजाइन पर काम कर रहे हों, तो मुझे लगता है कि ऐसा लक्ष्य रखना और उसे सचेत रूप से ध्यान में रखना अच्छा है। जब आप गाड़ी चलाना सीखते हैं, तो वे आपको जो सिद्धांत सिखाते हैं, उनमें से एक है कि कार को सड़क पर पेंट की गई पट्टियों के साथ हुड को संरेखित करके नहीं, बल्कि दूरी में किसी बिंदु पर निशाना लगाकर संरेखित करना है। भले ही आपको बस इस बात की परवाह हो कि अगले दस फीट में क्या होता है, यह सही उत्तर है। मुझे लगता है कि हम प्रोग्रामिंग भाषाओं के साथ भी ऐसा ही कर सकते हैं और करना चाहिए।
नोट्स
मेरा मानना है कि लिस्प मशीन लिस्प पहली भाषा थी जिसने इस सिद्धांत को मूर्त रूप दिया कि घोषणाएँ (डायनेमिक वैरिएबल को छोड़कर) केवल अनुकूलन सलाह थीं, और किसी सही प्रोग्राम का अर्थ नहीं बदलेंगी। कॉमन लिस्प ऐसा लगता है कि यह स्पष्ट रूप से बताने वाली पहली भाषा थी।
इस ड्राफ्ट को पढ़ने के लिए ट्रेवर ब्लैकवेल, रॉबर्ट मॉरिस और डैन गिफिन को धन्यवाद , तथा PyCon में बोलने के लिए मुझे आमंत्रित करने के लिए गुइडो वान रोसुम, जेरेमी हाइल्टन और शेष पायथन टीम को धन्यवाद।