नर्ड्स की प्रतिशोध
Originalमई 2002
"हम C++ प्रोग्रामरों के पीछे थे। हम उनमें से कई को Lisp की ओर आधे रास्ते खींचने में सफल रहे।"
- गाई स्टील, जावा स्पेक के सह-लेखक
सॉफ्टवेयर व्यवसाय में एक निरंतर संघर्ष है, नुकीले सिर वाले अकादमिकों और एक अन्य समान रूप से प्रभावशाली शक्ति, नुकीले बालों वाले बॉस के बीच। सभी को पता है कि नुकीले बालों वाला बॉस कौन है, है ना? मुझे लगता है कि तकनीकी दुनिया में अधिकांश लोग न केवल इस कार्टून चरित्र को पहचानते हैं, बल्कि अपने कंपनी में उस वास्तविक व्यक्ति को भी जानते हैं जिस पर यह आधारित है।
नुकीले बालों वाला बॉस चमत्कारिक रूप से दो गुणों को जोड़ता है जो अपने आप में सामान्य हैं, लेकिन एक साथ rarely देखे जाते हैं: (क) उसे तकनीक के बारे में कुछ भी नहीं पता है, और (ख) उसके पास इसके बारे में बहुत मजबूत राय है।
मान लीजिए, उदाहरण के लिए, आपको एक सॉफ्टवेयर का एक टुकड़ा लिखना है। नुकीले बालों वाले बॉस को यह नहीं पता कि यह सॉफ्टवेयर कैसे काम करना चाहिए, और वह एक प्रोग्रामिंग भाषा को दूसरी से नहीं पहचान सकता, फिर भी वह जानता है कि आपको इसे किस भाषा में लिखना चाहिए। बिल्कुल। वह सोचता है कि आपको इसे Java में लिखना चाहिए।
वह ऐसा क्यों सोचता है? चलिए नुकीले बालों वाले बॉस के दिमाग के अंदर झांकते हैं। जो वह सोच रहा है वह कुछ इस तरह है। Java एक मानक है। मुझे पता है कि यह होना चाहिए, क्योंकि मैं इसके बारे में प्रेस में हमेशा पढ़ता हूं। चूंकि यह एक मानक है, मैं इसका उपयोग करने के लिए परेशानी में नहीं पड़ूंगा। और इसका मतलब यह भी है कि हमेशा बहुत सारे Java प्रोग्रामर होंगे, इसलिए अगर मेरे लिए काम कर रहे प्रोग्रामर अचानक छोड़ देते हैं, जैसा कि प्रोग्रामर मेरे लिए रहस्यमय तरीके से हमेशा करते हैं, तो मैं उन्हें आसानी से बदल सकता हूं।
खैर, यह इतना असंगत नहीं लगता। लेकिन यह सब एक अनकही धारणा पर आधारित है, और वह धारणा गलत साबित होती है। नुकीले बालों वाला बॉस मानता है कि सभी प्रोग्रामिंग भाषाएं लगभग समान हैं। अगर ऐसा होता, तो वह सही होता। अगर भाषाएं सभी समान हैं, तो निश्चित रूप से, जो भी भाषा सभी अन्य लोग उपयोग कर रहे हैं, उसका उपयोग करें।
लेकिन सभी भाषाएं समान नहीं हैं, और मुझे लगता है कि मैं आपको बिना उनके बीच के अंतर में गए यह साबित कर सकता हूं। अगर आप 1992 में नुकीले बालों वाले बॉस से पूछते कि सॉफ्टवेयर किस भाषा में लिखा जाना चाहिए, तो वह आज की तरह ही बिना किसी हिचकिचाहट के जवाब देता। सॉफ्टवेयर को C++ में लिखा जाना चाहिए। लेकिन अगर भाषाएं सभी समान हैं, तो नुकीले बालों वाले बॉस की राय कभी क्यों बदलनी चाहिए? वास्तव में, Java के डेवलपर्स को एक नई भाषा बनाने की परवाह क्यों करनी चाहिए?
संभवतः, अगर आप एक नई भाषा बनाते हैं, तो इसका मतलब है कि आप सोचते हैं कि यह किसी तरह से बेहतर है जो लोगों के पास पहले से था। और वास्तव में, गोस्लिंग पहले Java श्वेत पत्र में स्पष्ट करते हैं कि Java को C++ के साथ कुछ समस्याओं को ठीक करने के लिए डिज़ाइन किया गया था। तो आपके पास यह है: भाषाएं सभी समान नहीं हैं। अगर आप नुकीले बालों वाले बॉस के दिमाग के माध्यम से Java के रास्ते का अनुसरण करते हैं और फिर Java के इतिहास के माध्यम से इसके मूल तक वापस जाते हैं, तो आप एक विचार रखते हैं जो उस धारणा का खंडन करता है जिससे आपने शुरुआत की थी।
तो, कौन सही है? जेम्स गोस्लिंग, या नुकीले बालों वाला बॉस? आश्चर्य की बात नहीं है, गोस्लिंग सही हैं। कुछ भाषाएं बेहतर हैं, कुछ समस्याओं के लिए, दूसरों की तुलना में। और आप जानते हैं, इससे कुछ दिलचस्प सवाल उठते हैं। Java को कुछ समस्याओं के लिए C++ से बेहतर होने के लिए डिज़ाइन किया गया था। कौन सी समस्याएं? Java कब बेहतर है और C++ कब? क्या ऐसी स्थितियां हैं जहां अन्य भाषाएं इनमें से किसी एक से बेहतर हैं?
जब आप इस सवाल पर विचार करना शुरू करते हैं, तो आपने वास्तव में एक कीड़ा खोल दिया है। अगर नुकीले बालों वाला बॉस को समस्या के पूरे जटिलता के बारे में सोचना पड़ा, तो यह उसके दिमाग को उड़ा देगा। जब तक वह सभी भाषाओं को समान मानता है, उसे केवल उस भाषा का चयन करना है जो सबसे अधिक गति में प्रतीत होती है, और चूंकि यह अधिक फैशन का सवाल है न कि तकनीक का, यहां तक कि वह शायद सही उत्तर प्राप्त कर सकता है। लेकिन अगर भाषाएं भिन्न होती हैं, तो उसे अचानक दो समवर्ती समीकरणों को हल करना होगा, यह पता लगाने की कोशिश करते हुए कि उसे हल करने के लिए आवश्यक समस्या के लिए बीस या अधिक प्रमुख भाषाओं की सापेक्ष उपयुक्तता के बीच एक इष्टतम संतुलन कैसे प्राप्त करें, और प्रत्येक के लिए प्रोग्रामर, पुस्तकालय आदि खोजने की संभावनाएं। अगर दरवाजे के दूसरी तरफ यही है, तो यह कोई आश्चर्य नहीं है कि नुकीले बालों वाला बॉस इसे खोलना नहीं चाहता।
यह मानने का नुकसान कि सभी प्रोग्रामिंग भाषाएं समान हैं, यह है कि यह सच नहीं है। लेकिन इसका लाभ यह है कि यह आपके जीवन को बहुत सरल बनाता है। और मुझे लगता है कि यही मुख्य कारण है कि यह विचार इतना व्यापक है। यह एक आरामदायक विचार है।
हमें पता है कि Java काफी अच्छा होना चाहिए, क्योंकि यह कूल, नई प्रोग्रामिंग भाषा है। या क्या यह है? अगर आप प्रोग्रामिंग भाषाओं की दुनिया को दूर से देखते हैं, तो ऐसा लगता है कि Java नवीनतम चीज है। (दूर से, आप केवल बड़े, चमकते बिलबोर्ड को देख सकते हैं जो सन द्वारा भुगतान किए गए हैं।) लेकिन अगर आप इस दुनिया को करीब से देखते हैं, तो आप पाते हैं कि कूलनेस के स्तर हैं। हैकर उपसंस्कृति के भीतर, एक और भाषा है जिसे Perl कहा जाता है जो Java की तुलना में बहुत कूल मानी जाती है। उदाहरण के लिए, स्लैशडॉट, Perl द्वारा उत्पन्न होता है। मुझे नहीं लगता कि आप उन लोगों को Java सर्वर पृष्ठों का उपयोग करते हुए पाएंगे। लेकिन एक और, नई भाषा है, जिसे Python कहा जाता है, जिसके उपयोगकर्ता Perl को नीचा दिखाते हैं, और अधिक पंखों में इंतजार कर रहे हैं।
अगर आप इन भाषाओं को क्रम में देखते हैं, Java, Perl, Python, तो आप एक दिलचस्प पैटर्न नोटिस करते हैं। कम से कम, आप यह पैटर्न नोटिस करते हैं अगर आप एक Lisp हैकर हैं। प्रत्येक एक के बाद एक Lisp के समान होता जा रहा है। Python यहां तक कि उन विशेषताओं की नकल करता है जिन्हें कई Lisp हैकर गलतियाँ मानते हैं। आप सरल Lisp कार्यक्रमों को Python में लाइन दर लाइन अनुवादित कर सकते हैं। यह 2002 है, और प्रोग्रामिंग भाषाएं लगभग 1958 के बराबर हो गई हैं।
गणित के साथ पकड़ना
मेरा मतलब है कि Lisp को सबसे पहले जॉन मैकार्थी द्वारा 1958 में खोजा गया था, और लोकप्रिय प्रोग्रामिंग भाषाएं केवल अब उन विचारों के साथ पकड़ रही हैं जो उन्होंने तब विकसित किए थे।
अब, यह कैसे सच हो सकता है? क्या कंप्यूटर प्रौद्योगिकी कुछ ऐसा नहीं है जो बहुत तेजी से बदलती है? मेरा मतलब है, 1958 में, कंप्यूटर रेफ्रिजरेटर के आकार के दैत्य थे जिनकी प्रोसेसिंग शक्ति एक कलाई घड़ी के बराबर थी। इतनी पुरानी तकनीक कैसे प्रासंगिक हो सकती है, न कि नवीनतम विकासों से बेहतर?
मैं आपको बताता हूं कि कैसे। यह इसलिए है क्योंकि Lisp वास्तव में एक प्रोग्रामिंग भाषा के रूप में डिज़ाइन नहीं किया गया था, कम से कम उस अर्थ में जो हम आज समझते हैं। जो हम प्रोग्रामिंग भाषा से समझते हैं वह कुछ है जिसका उपयोग हम कंप्यूटर को बताने के लिए करते हैं कि क्या करना है। मैकार्थी ने अंततः इस अर्थ में एक प्रोग्रामिंग भाषा विकसित करने का इरादा किया, लेकिन जो Lisp हमें वास्तव में मिला वह एक अलग चीज़ पर आधारित था जो उन्होंने एक सैद्धांतिक व्यायाम के रूप में किया था - ट्यूरिंग मशीन के लिए एक अधिक सुविधाजनक विकल्प को परिभाषित करने का प्रयास। जैसा कि मैकार्थी ने बाद में कहा,
Lisp को ट्यूरिंग मशीनों की तुलना में अधिक साफ दिखाने का एक और तरीका एक सार्वभौमिक Lisp फ़ंक्शन लिखना था और दिखाना था कि यह एक सार्वभौमिक ट्यूरिंग मशीन के विवरण की तुलना में संक्षिप्त और अधिक समझने योग्य है। यह Lisp फ़ंक्शन eval... था, जो एक Lisp अभिव्यक्ति के मूल्य की गणना करता है.... eval लिखने के लिए Lisp फ़ंक्शंस को Lisp डेटा के रूप में दर्शाने के लिए एक नोटेशन का आविष्कार करना आवश्यक था, और ऐसा नोटेशन पेपर के उद्देश्यों के लिए तैयार किया गया था बिना यह सोचे कि इसका उपयोग वास्तव में Lisp कार्यक्रमों को व्यक्त करने के लिए किया जाएगा।
इसके बाद जो हुआ वह यह था कि, 1958 के अंत में, स्टीव रसेल, मैकार्थी के एक ग्रेड छात्र, ने eval की इस परिभाषा को देखा और महसूस किया कि अगर वह इसे मशीन भाषा में अनुवादित करता है, तो परिणाम एक Lisp इंटरप्रेटर होगा।
यह उस समय एक बड़ा आश्चर्य था। यहां मैकार्थी ने बाद में एक साक्षात्कार में इसके बारे में क्या कहा:
स्टीव रसेल ने कहा, देखो, क्यों न मैं इस eval को प्रोग्राम करूं..., और मैंने उससे कहा, हो, हो, तुम सिद्धांत को प्रैक्टिस के साथ भ्रमित कर रहे हो, यह eval पढ़ने के लिए है, गणना के लिए नहीं। लेकिन उसने आगे बढ़कर किया। यानी, उसने अपने पेपर में eval को [IBM] 704 मशीन कोड में संकलित किया, बग्स को ठीक किया, और फिर इसे एक Lisp इंटरप्रेटर के रूप में विज्ञापित किया, जो निश्चित रूप से था। तो उस समय Lisp के पास मूल रूप से वही रूप था जो आज है....
अचानक, कुछ हफ्तों के भीतर मुझे लगता है, मैकार्थी ने पाया कि उसका सैद्धांतिक व्यायाम एक वास्तविक प्रोग्रामिंग भाषा में बदल गया है - और एक अधिक शक्तिशाली भाषा जो उसने इरादा किया था।
तो इस 1950 के दशक की भाषा के अप्रचलित न होने का संक्षिप्त स्पष्टीकरण यह है कि यह तकनीक नहीं बल्कि गणित था, और गणित पुराना नहीं होता। Lisp की तुलना करने के लिए सही चीज़ 1950 के दशक के हार्डवेयर नहीं, बल्कि, कहें, क्विकसॉर्ट एल्गोरिदम है, जिसे 1960 में खोजा गया था और जो अभी भी सबसे तेज़ सामान्य उद्देश्य की сорт है।
1950 के दशक से एक और भाषा है, फॉर्ट्रान, और यह भाषा डिज़ाइन के विपरीत दृष्टिकोण का प्रतिनिधित्व करती है। Lisp एक सिद्धांत का टुकड़ा था जो अप्रत्याशित रूप से एक प्रोग्रामिंग भाषा में बदल गया। फॉर्ट्रान जानबूझकर एक प्रोग्रामिंग भाषा के रूप में विकसित किया गया था, लेकिन जो हम अब एक बहुत निम्न-स्तरीय भाषा मानते हैं।
फॉर्ट्रान I, जो 1956 में विकसित किया गया था, वर्तमान फॉर्ट्रान से बहुत अलग था। फॉर्ट्रान I लगभग गणित के साथ असेंबली भाषा थी। कुछ तरीकों से यह हाल के असेंबली भाषाओं की तुलना में कम शक्तिशाली थी; उदाहरण के लिए, इसमें कोई उपरूटीन नहीं थे, केवल शाखाएं। वर्तमान फॉर्ट्रान अब शायद Lisp के करीब है बजाय फॉर्ट्रान I के।
Lisp और फॉर्ट्रान दो अलग-अलग विकासात्मक पेड़ों के तने थे, एक गणित में और एक मशीन आर्किटेक्चर में। ये दोनों पेड़ तब से एकीकृत हो रहे हैं। Lisp शक्तिशाली के रूप में शुरू हुआ, और अगले बीस वर्षों में तेज हो गया।所谓主流语言开始时快速,经过接下来的四十年逐渐变得更强大,直到现在它们中最先进的与Lisp相当接近。接近,但它们仍然缺少一些东西....
Lisp को अलग क्या बनाता है
जब इसे पहली बार विकसित किया गया था, Lisp ने नौ नए विचारों को समाहित किया। इनमें से कुछ हम अब सामान्य मानते हैं, अन्य केवल अधिक उन्नत भाषाओं में देखे जाते हैं, और दो अभी भी Lisp के लिए अद्वितीय हैं। नौ विचार हैं, मुख्यधारा द्वारा अपनाने के क्रम में,
शर्तें। एक शर्त एक if-then-else निर्माण है। हम अब इन्हें सामान्य मानते हैं, लेकिन फॉर्ट्रान I में ये नहीं थे। इसमें केवल एक शर्तीय गो-टू था जो अंतर्निहित मशीन निर्देश पर आधारित था।
एक फ़ंक्शन प्रकार। Lisp में, फ़ंक्शन एक डेटा प्रकार हैं जैसे पूर्णांक या स्ट्रिंग। उनके पास एक शाब्दिक प्रतिनिधित्व होता है, उन्हें वेरिएबल में संग्रहीत किया जा सकता है, उन्हें तर्क के रूप में पास किया जा सकता है, आदि।
पुनरावृत्ति। Lisp पहला प्रोग्रामिंग भाषा था जो इसे समर्थन करता था।
गतिशील टाइपिंग। Lisp में, सभी वेरिएबल प्रभावी रूप से पॉइंटर्स हैं। मान वे हैं जिनके प्रकार होते हैं, वेरिएबल नहीं, और वेरिएबल को असाइन या बाइंड करना पॉइंटर्स की कॉपी करना होता है, न कि वे किस पर इंगित करते हैं।
गंदगी-संग्रहण।
व्यक्तियों से बने कार्यक्रम। Lisp कार्यक्रम अभिव्यक्तियों के पेड़ होते हैं, जिनमें से प्रत्येक एक मान लौटाता है। यह फॉर्ट्रान और अधिकांश उत्तराधिकार भाषाओं के विपरीत है, जो अभिव्यक्तियों और बयानों के बीच भेद करते हैं।
फॉर्ट्रान I में इस भेद को रखना स्वाभाविक था क्योंकि आप बयानों को नेस्ट नहीं कर सकते थे। और इसलिए जबकि आपको गणित के काम करने के लिए अभिव्यक्तियों की आवश्यकता थी, कुछ और को मान लौटाने का कोई मतलब नहीं था, क्योंकि इसके लिए कुछ भी इंतजार नहीं कर सकता था।
यह सीमा ब्लॉक-संरचित भाषाओं के आगमन के साथ समाप्त हो गई, लेकिन तब तक बहुत देर हो चुकी थी। अभिव्यक्तियों और बयानों के बीच का भेद स्थापित हो गया था। यह फॉर्ट्रान से अल्गोल में फैल गया और फिर उनके दोनों वंशजों में।
एक प्रतीक प्रकार। प्रतीक प्रभावी रूप से स्ट्रिंग्स के लिए हैश टेबल में पॉइंटर्स होते हैं। तो आप एक पॉइंटर की तुलना करके समानता का परीक्षण कर सकते हैं, न कि प्रत्येक वर्ण की तुलना करके।
संकेतों और स्थिरांक के पेड़ों का उपयोग करके कोड के लिए एक नोटेशन।
पूरी भाषा हमेशा वहां होती है। पढ़ने के समय, संकलन के समय और रनटाइम के बीच कोई वास्तविक भेद नहीं है। आप पढ़ते समय कोड को संकलित या चला सकते हैं, संकलन करते समय कोड को पढ़ या चला सकते हैं, और रनटाइम पर कोड को पढ़ या संकलित कर सकते हैं।
पढ़ने के समय कोड चलाना उपयोगकर्ताओं को Lisp की सिंटैक्स को फिर से प्रोग्राम करने की अनुमति देता है; संकलन के समय कोड चलाना मैक्रोज़ का आधार है; रनटाइम पर संकलन करना Emacs जैसे कार्यक्रमों में Lisp के उपयोग के रूप में एक एक्सटेंशन भाषा का आधार है; और रनटाइम पर पढ़ना कार्यक्रमों को s-व्यक्तियों का उपयोग करके संवाद करने में सक्षम बनाता है, एक विचार जिसे हाल ही में XML के रूप में फिर से आविष्कार किया गया है।
जब Lisp पहली बार प्रकट हुआ, ये विचार सामान्य प्रोग्रामिंग प्रथा से बहुत दूर थे, जो मुख्य रूप से 1950 के दशक के अंत में उपलब्ध हार्डवेयर द्वारा निर्धारित की गई थी। समय के साथ, डिफ़ॉल्ट भाषा, जो लोकप्रिय भाषाओं की एक श्रृंखला में समाहित है, धीरे-धीरे Lisp की ओर विकसित हुई है। विचार 1-5 अब व्यापक हैं। संख्या 6 मुख्यधारा में दिखाई देने लगी है। Python में 7 का एक रूप है, हालांकि इसके लिए कोई सिंटैक्स नहीं लगता।
जहां तक संख्या 8 का सवाल है, यह शायद सबसे दिलचस्प है। विचार 8 और 9 केवल आकस्मिक रूप से Lisp का हिस्सा बने, क्योंकि स्टीव रसेल ने कुछ ऐसा लागू किया जो मैकार्थी ने कभी लागू करने का इरादा नहीं किया था। और फिर भी ये विचार Lisp की अजीब उपस्थिति और इसके सबसे विशिष्ट विशेषताओं के लिए जिम्मेदार साबित होते हैं। Lisp अजीब दिखता है न कि इसलिए कि इसकी एक अजीब सिंटैक्स है, बल्कि इसलिए कि इसकी कोई सिंटैक्स नहीं है; आप कार्यक्रमों को सीधे उन पार्स पेड़ों में व्यक्त करते हैं जो अन्य भाषाओं के पार्स किए जाने पर पीछे के दृश्य में बनते हैं, और ये पेड़ सूचियों से बने होते हैं, जो Lisp डेटा संरचनाएं हैं।
भाषा को इसकी अपनी डेटा संरचनाओं में व्यक्त करना एक बहुत शक्तिशाली विशेषता साबित होता है। विचार 8 और 9 मिलकर यह मतलब रखते हैं कि आप ऐसे कार्यक्रम लिख सकते हैं जो कार्यक्रम लिखते हैं। यह एक अजीब विचार की तरह लग सकता है, लेकिन यह Lisp में एक सामान्य बात है। इसे करने का सबसे सामान्य तरीका कुछ ऐसा है जिसे मैक्रो कहा जाता है।
"मैक्रो" शब्द Lisp में वही नहीं है जो अन्य भाषाओं में है। एक Lisp मैक्रो कुछ भी हो सकता है, एक संक्षिप्तता से लेकर एक नई भाषा के लिए एक संकलक तक। अगर आप वास्तव में Lisp को समझना चाहते हैं, या बस अपने प्रोग्रामिंग क्षितिज का विस्तार करना चाहते हैं, तो मैं मैक्रोज़ के बारे में अधिक जानने की सिफारिश करूंगा।
मैक्रोज़ (Lisp के अर्थ में) अभी भी, मेरी जानकारी के अनुसार, Lisp के लिए अद्वितीय हैं। यह आंशिक रूप से इस कारण से है कि मैक्रोज़ रखने के लिए आपको शायद अपनी भाषा को Lisp जितना अजीब बनाना होगा। यह भी हो सकता है कि अगर आप उस अंतिम शक्ति के स्तर को जोड़ते हैं, तो आप अब एक नई भाषा का आविष्कार करने का दावा नहीं कर सकते, बल्कि केवल Lisp का एक नया उपभाषा।
मैं इसे ज्यादातर मजाक के रूप में उल्लेख करता हूं, लेकिन यह सच है। अगर आप एक भाषा को परिभाषित करते हैं जिसमें car, cdr, cons, quote, cond, atom, eq, और एक नोटेशन है जो सूचियों के रूप में व्यक्त की गई फ़ंक्शंस के लिए है, तो आप इसके माध्यम से बाकी सभी Lisp का निर्माण कर सकते हैं। वास्तव में, यह Lisp की परिभाषित गुणवत्ता है: यह इस तरह से बनाने के लिए था कि मैकार्थी ने Lisp को जो आकार दिया है।
जहां भाषाएं महत्वपूर्ण हैं
तो मान लीजिए कि Lisp वास्तव में एक प्रकार की सीमा का प्रतिनिधित्व करता है जिसे मुख्यधारा की भाषाएं असममित रूप से प्राप्त कर रही हैं - क्या इसका मतलब है कि आपको वास्तव में इसका उपयोग सॉफ्टवेयर लिखने के लिए करना चाहिए? एक कम शक्तिशाली भाषा का उपयोग करके आप कितना खोते हैं? क्या कभी-कभी यह अधिक समझदारी नहीं है कि आप नवाचार के बहुत किनारे पर न हों? और क्या लोकप्रियता कुछ हद तक अपनी खुद की औचित्य नहीं है? क्या नुकीले बालों वाला बॉस सही नहीं है, उदाहरण के लिए, एक ऐसी भाषा का उपयोग करना चाहता है जिसके लिए वह आसानी से प्रोग्रामर हायर कर सके?
बेशक, ऐसे प्रोजेक्ट हैं जहां प्रोग्रामिंग भाषा का चयन ज्यादा मायने नहीं रखता। सामान्यतः, जितनी अधिक मांग वाली एप्लिकेशन होती है, उतनी ही अधिक लाभप्रदता आपको एक शक्तिशाली भाषा का उपयोग करने से मिलती है। लेकिन कई प्रोजेक्ट बिल्कुल भी मांग वाले नहीं होते। अधिकांश प्रोग्रामिंग शायद छोटे गोंद कार्यक्रम लिखने में होती है, और छोटे गोंद कार्यक्रमों के लिए आप किसी भी भाषा का उपयोग कर सकते हैं जिससे आप पहले से परिचित हैं और जिसमें आपके करने के लिए अच्छे पुस्तकालय हैं। अगर आपको बस एक Windows ऐप से दूसरे में डेटा फीड करने की आवश्यकता है, तो निश्चित रूप से, Visual Basic का उपयोग करें।
आप Lisp में भी छोटे गोंद कार्यक्रम लिख सकते हैं (मैं इसका उपयोग एक डेस्कटॉप कैलकुलेटर के रूप में करता हूं), लेकिन Lisp जैसी भाषाओं के लिए सबसे बड़ा लाभ स्पेक्ट्रम के दूसरे छोर पर है, जहां आपको कठिन समस्याओं को हल करने के लिए जटिल कार्यक्रम लिखने की आवश्यकता होती है, तीव्र प्रतिस्पर्धा के सामने। एक अच्छा उदाहरण है एयरलाइन किराया खोज कार्यक्रम जो ITA सॉफ़्टवेयर ने ऑर्बिट्ज़ को लाइसेंस दिया है। ये लोग पहले से ही दो बड़े, स्थापित प्रतिस्पर्धियों, ट्रैवेलocity और एक्सपीडिया द्वारा प्रभुत्व वाले बाजार में प्रवेश कर गए, और तकनीकी रूप से उन्हें अपमानित करने में सफल रहे हैं।
ITA के आवेदन का मूल एक 200,000 लाइन का कॉमन Lisp कार्यक्रम है जो उनके प्रतिस्पर्धियों की तुलना में कई आदेशों से अधिक संभावनाओं की खोज करता है, जो स्पष्ट रूप से अभी भी मेनफ्रेम-युग की प्रोग्रामिंग तकनीकों का उपयोग कर रहे हैं। (हालांकि ITA भी एक अर्थ में मेनफ्रेम-युग की प्रोग्रामिंग भाषा का उपयोग कर रहा है।) मैंने कभी भी ITA का कोई कोड नहीं देखा है, लेकिन उनके शीर्ष हैकरों में से एक के अनुसार वे बहुत सारे मैक्रोज़ का उपयोग करते हैं, और मुझे यह सुनकर आश्चर्य नहीं हुआ।
केंद्रापसारक बल
मैं यह नहीं कह रहा हूं कि असामान्य तकनीकों का उपयोग करने का कोई खर्च नहीं है। नुकीले बालों वाला बॉस इस बारे में चिंता करने में पूरी तरह से गलत नहीं है। लेकिन क्योंकि वह जोखिमों को नहीं समझता, वह उन्हें बढ़ा-चढ़ा कर पेश करता है।
मैं तीन समस्याओं के बारे में सोच सकता हूं जो कम सामान्य भाषाओं के उपयोग से उत्पन्न हो सकती हैं। आपके कार्यक्रम अन्य भाषाओं में लिखे गए कार्यक्रमों के साथ अच्छी तरह से काम नहीं कर सकते। आपके पास अपनी सुविधा के लिए कम पुस्तकालय हो सकते हैं। और आपको प्रोग्रामर हायर करने में परेशानी हो सकती है।
इनमें से प्रत्येक समस्या कितनी बड़ी है? पहले की महत्वता इस पर निर्भर करती है कि क्या आपके पास पूरे सिस्टम पर नियंत्रण है। अगर आप ऐसा सॉफ्टवेयर लिख रहे हैं जिसे एक दूरस्थ उपयोगकर्ता की मशीन पर एक बग-युक्त, बंद ऑपरेटिंग सिस्टम (मैं कोई नाम नहीं लूंगा) पर चलाना है, तो आपके एप्लिकेशन को उसी भाषा में लिखने के लिए कुछ लाभ हो सकते हैं जैसे OS। लेकिन अगर आप पूरे सिस्टम पर नियंत्रण रखते हैं और सभी भागों का स्रोत कोड आपके पास है, जैसा कि ITA के पास है, तो आप जो चाहें भाषाएं उपयोग कर सकते हैं। अगर कोई असंगति उत्पन्न होती है, तो आप इसे स्वयं ठीक कर सकते हैं।
सर्वर-आधारित अनुप्रयोगों में आप सबसे उन्नत तकनीकों का उपयोग करने में सफल हो सकते हैं, और मुझे लगता है कि यही कारण है कि जोनाथन एरिक्सन इसे "प्रोग्रामिंग भाषा पुनर्जागरण" कहते हैं। यही कारण है कि हम Perl और Python जैसी नई भाषाओं के बारे में सुनते हैं। हम इन भाषाओं के बारे में इसलिए नहीं सुन रहे हैं क्योंकि लोग उनका उपयोग Windows ऐप्स लिखने के लिए कर रहे हैं, बल्कि इसलिए कि लोग उनका उपयोग सर्वरों पर कर रहे हैं। और जैसे-जैसे सॉफ्टवेयर डेस्कटॉप से सर्वरों पर स्थानांतरित होता है (एक भविष्य जिसे यहां तक कि माइक्रोसॉफ्ट भी स्वीकार कर चुका है), मध्य-मार्ग की तकनीकों का उपयोग करने का दबाव कम होता जाएगा।
जहां तक पुस्तकालयों का सवाल है, उनकी महत्वता भी अनुप्रयोग पर निर्भर करती है। कम मांग वाली समस्याओं के लिए, पुस्तकालयों की उपलब्धता भाषा की अंतर्निहित शक्ति को पार कर सकती है। ब्रेकइवन पॉइंट कहां है? इसे सटीक रूप से कहना कठिन है, लेकिन जहां भी यह है, यह किसी भी चीज़ से कम है जिसे आप अनुप्रयोग कहने की संभावना रखते हैं। अगर कोई कंपनी खुद को सॉफ्टवेयर व्यवसाय में मानती है, और वे एक ऐसा एप्लिकेशन लिख रहे हैं जो उनके उत्पादों में से एक होगा, तो यह शायद कई हैकरों को शामिल करेगा और इसे लिखने में कम से कम छह महीने लगेंगे। उस आकार की परियोजना में, शक्तिशाली भाषाएं शायद पूर्व-निर्मित पुस्तकालयों की सुविधा को पार करना शुरू कर देती हैं।
नुकीले बालों वाले बॉस की तीसरी चिंता, प्रोग्रामर हायर करने में कठिनाई, मुझे लगता है कि यह एक लाल हेरिंग है। आखिरकार, आपको कितने हैकरों को हायर करने की आवश्यकता है? निश्चित रूप से अब हम सभी जानते हैं कि सॉफ्टवेयर को दस से कम लोगों की टीमों द्वारा सबसे अच्छा विकसित किया जाता है। और आपको किसी भी भाषा के लिए उस पैमाने पर हैकरों को हायर करने में परेशानी नहीं होनी चाहिए जिसे कोई भी कभी सुना है। अगर आप दस Lisp हैकर नहीं ढूंढ सकते, तो आपकी कंपनी शायद सॉफ्टवेयर विकसित करने के लिए गलत शहर में है।
वास्तव में, एक अधिक शक्तिशाली भाषा का चयन करना शायद आपकी आवश्यक टीम के आकार को कम करता है, क्योंकि (क) अगर आप एक अधिक शक्तिशाली भाषा का उपयोग करते हैं, तो आपको शायद उतने हैकरों की आवश्यकता नहीं होगी, और (ख) जो हैकर अधिक उन्नत भाषाओं में काम करते हैं वे अधिक बुद्धिमान होने की संभावना रखते हैं।
मैं यह नहीं कह रहा हूं कि आपको "मानक" तकनीकों का उपयोग करने के लिए बहुत दबाव नहीं मिलेगा। Viaweb (अब Yahoo Store) में, हमने Lisp का उपयोग करके VCs और संभावित अधिग्रहणकर्ताओं के बीच कुछ भौंहें उठाईं। लेकिन हमने "औद्योगिक शक्ति" सर्वरों जैसे सन के बजाय सामान्य इंटेल बॉक्सों का उपयोग करके भी भौंहें उठाईं, एक वास्तविक व्यावसायिक OS जैसे Windows NT के बजाय एक तब-अज्ञात ओपन-सोर्स यूनिक्स वेरिएंट का उपयोग करके, एक कथित ई-कॉमर्स मानक को नजरअंदाज करके जिसे SET कहा जाता है जिसे अब कोई भी याद नहीं करता, और इसी तरह।
आपको सूटधारी लोगों को आपके लिए तकनीकी निर्णय लेने की अनुमति नहीं देनी चाहिए। क्या यह कुछ संभावित अधिग्रहणकर्ताओं को यह चिंता करता है कि हमने Lisp का उपयोग किया? कुछ, थोड़ी, लेकिन अगर हमने Lisp का उपयोग नहीं किया होता, तो हम उस सॉफ्टवेयर को नहीं लिख पाते जो उन्हें हमें खरीदने के लिए प्रेरित करता। जो उनके लिए एक विसंगति की तरह लग रहा था, वास्तव में कारण और प्रभाव था।
अगर आप एक स्टार्टअप शुरू करते हैं, तो अपने उत्पाद को VCs या संभावित अधिग्रहणकर्ताओं को खुश करने के लिए डिज़ाइन न करें। अपने उत्पाद को उपयोगकर्ताओं को खुश करने के लिए डिज़ाइन करें। अगर आप उपयोगकर्ताओं को जीतते हैं, तो बाकी सब कुछ अनुसरण करेगा। और अगर आप नहीं करते हैं, तो किसी को परवाह नहीं होगी कि आपकी तकनीकी पसंद कितनी आरामदायक रूप से पारंपरिक थी।
औसत होने की लागत
कम शक्तिशाली भाषा का उपयोग करके आप कितना खोते हैं? इसके बारे में वास्तव में कुछ डेटा है।
शक्ति का सबसे सुविधाजनक माप शायद कोड का आकार है। उच्च-स्तरीय भाषाओं का उद्देश्य आपको बड़े अमूर्तता देना है - बड़े ईंटें, जैसे कि, ताकि आपको एक निश्चित आकार की दीवार बनाने के लिए उतनी ही आवश्यकता न हो। इसलिए जितनी अधिक शक्तिशाली भाषा होगी, कार्यक्रम उतना ही छोटा होगा (निश्चित रूप से, केवल वर्णों में नहीं, बल्कि अलग-अलग तत्वों में)।
एक अधिक शक्तिशाली भाषा आपको छोटे कार्यक्रम लिखने में कैसे सक्षम बनाती है? एक तकनीक जिसका आप उपयोग कर सकते हैं, अगर भाषा आपको अनुमति देती है, तो उसे बॉटम-अप प्रोग्रामिंग कहा जाता है। इसके बजाय कि आप अपने एप्लिकेशन को बेस भाषा में बस लिखें, आप बेस भाषा के ऊपर एक भाषा बनाते हैं जो आपके जैसे कार्यक्रम लिखने के लिए है, फिर उसमें अपना कार्यक्रम लिखते हैं। संयुक्त कोड उस स्थिति की तुलना में बहुत छोटा हो सकता है यदि आपने अपना पूरा कार्यक्रम बेस भाषा में लिखा होता - वास्तव में, यही अधिकांश संकुचन एल्गोरिदम का काम करने का तरीका है। एक बॉटम-अप प्रोग्राम को संशोधित करना भी आसान होना चाहिए, क्योंकि कई मामलों में भाषा स्तर को बिल्कुल भी बदलने की आवश्यकता नहीं होगी।
कोड का आकार महत्वपूर्ण है, क्योंकि एक कार्यक्रम लिखने में लगने वाला समय मुख्य रूप से इसकी लंबाई पर निर्भर करता है। अगर आपका कार्यक्रम किसी अन्य भाषा में तीन गुना लंबा होगा, तो इसे लिखने में तीन गुना समय लगेगा - और आप इसे अधिक लोगों को हायर करके नहीं बदल सकते, क्योंकि एक निश्चित आकार के बाद नए हायर वास्तव में एक शुद्ध हानि होते हैं। फ्रेड ब्रूक्स ने इस घटना का वर्णन अपने प्रसिद्ध पुस्तक The Mythical Man-Month में किया, और मैंने जो कुछ भी देखा है उसने जो कहा है उसे पुष्टि करने की प्रवृत्ति दिखाई है।
तो अगर आप Lisp में अपने कार्यक्रम लिखते हैं तो आपके कार्यक्रम कितने छोटे होते हैं? उदाहरण के लिए, Lisp बनाम C के लिए मैंने जो अधिकतर संख्याएं सुनी हैं, वे लगभग 7-10x रही हैं। लेकिन ITA के बारे में एक हालिया लेख में New Architect पत्रिका ने कहा कि "एक लाइन Lisp 20 लाइनों C को बदल सकती है," और चूंकि यह लेख ITA के अध्यक्ष के उद्धरणों से भरा हुआ था, मैं मानता हूं कि उन्होंने यह संख्या ITA से प्राप्त की। अगर ऐसा है तो हम इसमें कुछ विश्वास रख सकते हैं; ITA का सॉफ्टवेयर बहुत सारे C और C++ के साथ-साथ Lisp को भी शामिल करता है, इसलिए वे अनुभव से बोल रहे हैं।
मेरा अनुमान है कि ये गुणांक भी स्थिर नहीं हैं। मुझे लगता है कि वे तब बढ़ते हैं जब आप कठिन समस्याओं का सामना करते हैं और जब आपके पास अधिक बुद्धिमान प्रोग्रामर होते हैं। एक वास्तव में अच्छा हैकर बेहतर उपकरणों से अधिक निकाल सकता है।
किसी भी मामले में, अगर आप ITA के साथ प्रतिस्पर्धा करने का निर्णय लेते हैं और अपने सॉफ्टवेयर को C में लिखने का चयन करते हैं, तो वे आपसे बीस गुना तेजी से सॉफ्टवेयर विकसित करने में सक्षम होंगे। अगर आप एक नए फीचर पर एक साल बिताते हैं, तो वे इसे तीन सप्ताह से कम समय में दोहराने में सक्षम होंगे। जबकि अगर वे केवल तीन महीने कुछ नया विकसित करने में बिताते हैं, तो आपको भी इसे प्राप्त करने में पांच साल लगेंगे।
और आप जानते हैं क्या? यह सबसे अच्छा मामला है। जब आप कोड-आकार अनुपात के बारे में बात करते हैं, तो आप निहित रूप से मान रहे हैं कि आप वास्तव में कमजोर भाषा में कार्यक्रम लिख सकते हैं। लेकिन वास्तव में प्रोग्रामरों के लिए जो कुछ भी किया जा सकता है, उस पर सीमाएं हैं। अगर आप एक कठिन समस्या को एक बहुत निम्न-स्तरीय भाषा के साथ हल करने की कोशिश कर रहे हैं, तो आप एक बिंदु पर पहुंचते हैं जहां एक बार में अपने सिर में रखने के लिए बहुत कुछ होता है।
तो जब मैं कहता हूं कि ITA के काल्पनिक प्रतिस्पर्धी को ITA द्वारा तीन महीने में लिखी गई किसी चीज़ को दोहराने में पांच साल लगेंगे, तो मेरा मतलब है कि अगर कुछ गलत नहीं होता है तो पांच साल। वास्तव में, अधिकांश कंपनियों में चीजें जिस तरह से काम करती हैं, किसी भी विकास परियोजना को जो पांच साल लेगी, शायद कभी खत्म नहीं होगी।
मैं मानता हूं कि यह एक चरम मामला है। ITA के हैकर असामान्य रूप से स्मार्ट लगते हैं, और C एक बहुत निम्न-स्तरीय भाषा है। लेकिन एक प्रतिस्पर्धी बाजार में, यहां तक कि दो या तीन से एक का अंतर भी यह सुनिश्चित करने के लिए पर्याप्त होगा कि आप हमेशा पीछे रहेंगे।
एक नुस्खा
यह वह प्रकार की संभावना है जिसके बारे में नुकीले बालों वाला बॉस सोचना भी नहीं चाहता। और इसलिए उनमें से अधिकांश नहीं करते। क्योंकि, आप जानते हैं, जब यह सब आता है, तो नुकीले बालों वाले बॉस को परवाह नहीं है कि उसकी कंपनी को धक्का लगता है, जब तक कि कोई यह साबित नहीं कर सकता कि यह उसकी गलती है। उसके लिए सबसे सुरक्षित योजना यह है कि वह झुंड के केंद्र के करीब रहे।
बड़ी संगठनों के भीतर, इस दृष्टिकोण का वर्णन करने के लिए उपयोग की जाने वाली वाक्यांश "उद्योग की सर्वश्रेष्ठ प्रथा" है। इसका उद्देश्य नुकीले बालों वाले बॉस को जिम्मेदारी से बचाना है: अगर वह कुछ चुनता है जो "उद्योग की सर्वश्रेष्ठ प्रथा" है, और कंपनी हार जाती है, तो उसे दोष नहीं दिया जा सकता। उसने नहीं चुना, उद्योग ने किया।
मुझे विश्वास है कि यह शब्द मूल रूप से लेखा विधियों आदि का वर्णन करने के लिए उपयोग किया गया था। इसका अर्थ, मोटे तौर पर, कुछ अजीब मत करो। और लेखा में यह शायद एक अच्छा विचार है। "कटिंग-एज" और "लेखा" एक साथ अच्छा नहीं लगता। लेकिन जब आप इस मानदंड को प्रौद्योगिकी के निर्णयों में लाते हैं, तो आप गलत उत्तर प्राप्त करना शुरू करते हैं।
प्रौद्योगिकी अक्सर कटिंग-एज होनी चाहिए। प्रोग्रामिंग भाषाओं में, जैसा कि एरान गेट ने बताया है, "उद्योग की सर्वश्रेष्ठ प्रथा" वास्तव में आपको जो मिलती है वह सबसे अच्छी नहीं है, बल्कि केवल औसत है। जब एक निर्णय आपको अधिक आक्रामक प्रतिस्पर्धियों की तुलना में एक अंश की दर पर सॉफ्टवेयर विकसित करने का कारण बनता है, तो "सर्वश्रेष्ठ प्रथा" एक गलत नाम है।
तो यहां हमारे पास दो जानकारी के टुकड़े हैं जो मुझे लगता है कि बहुत मूल्यवान हैं। वास्तव में, मैं इसे अपने अनुभव से जानता हूं। संख्या 1, भाषाएं शक्ति में भिन्न होती हैं। संख्या 2, अधिकांश प्रबंधक जानबूझकर इसे नजरअंदाज करते हैं। इनके बीच, ये दो तथ्य सचमुच पैसे बनाने के लिए एक नुस्खा हैं। ITA इस नुस्खा का एक उदाहरण है। अगर आप सॉफ्टवेयर व्यवसाय में जीतना चाहते हैं, तो बस उस कठिन समस्या को लें जिसे आप पा सकते हैं, सबसे शक्तिशाली भाषा का उपयोग करें जिसे आप प्राप्त कर सकते हैं, और अपने प्रतिस्पर्धियों के नुकीले बालों वाले बॉस के औसत पर लौटने की प्रतीक्षा करें।
परिशिष्ट: शक्ति
प्रोग्रामिंग भाषाओं की सापेक्ष शक्ति के बारे में जो मैं कह रहा हूं, उसके एक उदाहरण के रूप में, निम्नलिखित समस्या पर विचार करें। हम एक फ़ंक्शन लिखना चाहते हैं जो संचित करने वाले उत्पन्न करता है - एक फ़ंक्शन जो एक संख्या n लेता है, और एक अन्य संख्या i लेता है और n को i से बढ़ा देता है।
(यह बढ़ा देता है, न कि जोड़ता है। एक संचित करने वाले को संचित करना होता है।)
कॉमन Lisp में यह होगा
(defun foo (n)
(lambda (i) (incf n i)))
और Perl 5 में,
sub foo {
my ($n) = @_;
sub {$n += shift}
}
जिसमें Lisp संस्करण की तुलना में अधिक तत्व हैं क्योंकि आपको Perl में मैन्युअल रूप से पैरामीटर निकालने होते हैं।
Smalltalk में कोड Lisp की तुलना में थोड़ा लंबा है
foo: n
|s|
s := n.
^[:i| s := s+i. ]
क्योंकि सामान्यतः लेक्सिकल वेरिएबल काम करते हैं, आप पैरामीटर को असाइन नहीं कर सकते, इसलिए आपको एक नया वेरिएबल s बनाना होता है।
Javascript में उदाहरण फिर से थोड़ा लंबा है, क्योंकि Javascript बयानों और अभिव्यक्तियों के बीच भेद बनाए रखता है, इसलिए आपको मान लौटाने के लिए स्पष्ट लौटाने वाले बयानों की आवश्यकता होती है:
function foo(n) {
return function (i) {
return n += i } }
(इसे निष्पक्षता से कहें, Perl भी इस भेद को बनाए रखता है, लेकिन इसे सामान्य Perl शैली में निपटता है जिससे आप लौटाने को छोड़ सकते हैं।)
अगर आप Lisp/Perl/Smalltalk/Javascript कोड को Python में अनुवादित करने की कोशिश करते हैं, तो आप कुछ सीमाओं का सामना करते हैं। क्योंकि Python पूरी तरह से लेक्सिकल वेरिएबल का समर्थन नहीं करता है, आपको n के मान को रखने के लिए एक डेटा संरचना बनानी होती है। और हालांकि Python में एक फ़ंक्शन डेटा प्रकार है, लेकिन इसके लिए कोई शाब्दिक प्रतिनिधित्व नहीं है (जब तक कि शरीर केवल एकल अभिव्यक्ति न हो) इसलिए आपको लौटाने के लिए एक नामित फ़ंक्शन बनाना होगा। यह है जो आपको अंततः मिलता है:
def foo(n):
s = [n]
def bar(i):
s[0] += i
return s[0]
return bar
Python उपयोगकर्ता वैध रूप से पूछ सकते हैं कि वे क्यों नहीं लिख सकते
def foo(n):
return lambda i: return n += i
या यहां तक कि
def foo(n):
lambda i: n += i
और मेरा अनुमान है कि वे शायद एक दिन ऐसा करेंगे। (लेकिन अगर वे Python को Lisp में विकसित होने के लिए इंतजार नहीं करना चाहते, तो वे हमेशा बस...)
OO भाषाओं में, आप सीमित रूप से एक क्लोजर (एक फ़ंक्शन जो संलग्न स्कोप में परिभाषित वेरिएबल्स का संदर्भ देता है) का अनुकरण कर सकते हैं, एक वर्ग को एक विधि और एक क्षेत्र के साथ परिभाषित करके प्रत्येक वेरिएबल को एक संलग्न स्कोप से बदलने के लिए। यह प्रोग्रामर को उस प्रकार के कोड विश्लेषण करने के लिए मजबूर करता है जो एक पूर्ण लेक्सिकल स्कोप के समर्थन वाली भाषा में संकलक द्वारा किया जाएगा, और यह तब काम नहीं करेगा जब एक से अधिक फ़ंक्शन एक ही वेरिएबल का संदर्भ देते हैं, लेकिन यह सरल मामलों में पर्याप्त है।
Python विशेषज्ञों का मानना है कि यह Python में समस्या को हल करने का पसंदीदा तरीका है, या तो लिखते हुए
def foo(n):
class acc:
def __init__(self, s):
self.s = s
def inc(self, i):
self.s += i
return self.s
return acc(n).inc
या
class foo:
def __init__(self, n):
self.n = n
def __call__(self, i):
self.n += i
return self.n
मैं इन्हें शामिल करता हूं क्योंकि मैं नहीं चाहता कि Python समर्थक कहें कि मैं भाषा को गलत तरीके से प्रस्तुत कर रहा हूं, लेकिन दोनों मुझे पहले संस्करण की तुलना में अधिक जटिल लगते हैं। आप वही कर रहे हैं, एक अलग जगह स्थापित कर रहे हैं जो संचित करने वाले को रखने के लिए है; यह केवल एक सूची के सिर के बजाय एक वस्तु में एक क्षेत्र है। और इन विशेष, आरक्षित क्षेत्र नामों का उपयोग, विशेष रूप से call, थोड़ा हैक जैसा लगता है।
Perl और Python के बीच की प्रतिद्वंद्विता में, Python हैकरों का दावा है कि Python Perl के लिए एक अधिक सुरुचिपूर्ण विकल्प है, लेकिन यह मामला दिखाता है कि शक्ति अंतिम सुरुचिपूर्णता है: Perl कार्यक्रम सरल है (कम तत्व हैं), भले ही सिंटैक्स थोड़ा बदसूरत हो।
अन्य भाषाओं के बारे में क्या? इस वार्ता में उल्लेखित अन्य भाषाओं - फॉर्ट्रान, C, C++, Java, और Visual Basic - में यह स्पष्ट नहीं है कि क्या आप वास्तव में इस समस्या को हल कर सकते हैं। केन एंडरसन का कहना है कि निम्नलिखित कोड Java में लगभग जितना संभव है:
public interface Inttoint {
public int call(int i);
}
public static Inttoint foo(final int n) {
return new Inttoint() {
int s = n;
public int call(int i) {
s = s + i;
return s;
}};
}
यह स्पेक के अनुसार नहीं है क्योंकि यह केवल पूर्णांकों के लिए काम करता है। Java हैकरों के साथ कई ईमेल आदान-प्रदान के बाद, मैं कहूंगा कि एक उचित बहुरूपता संस्करण लिखना जो पिछले उदाहरणों की तरह व्यवहार करता है, कहीं न कहीं damned awkward और असंभव के बीच है। अगर कोई इसे लिखना चाहता है, तो मैं इसे देखने के लिए बहुत उत्सुक रहूंगा, लेकिन मैंने व्यक्तिगत रूप से समय समाप्त कर दिया है।
यह सच नहीं है कि आप अन्य भाषाओं में इस समस्या को हल नहीं कर सकते। तथ्य यह है कि ये सभी भाषाएं ट्यूरिंग-समान हैं, इसका मतलब है कि, सख्ती से बोलते हुए, आप इनमें से किसी भी भाषा में कोई भी कार्यक्रम लिख सकते हैं। तो आप इसे कैसे करेंगे? सीमा के मामले में, एक Lisp इंटरप्रेटर लिखकर कम शक्तिशाली भाषा में।
यह मजाक की तरह लगता है, लेकिन यह बड़े प्रोग्रामिंग प्रोजेक्ट्स में विभिन्न डिग्री में इतनी बार होता है कि इस घटना का एक नाम है, ग्रीनस्पन का दसवां नियम:
किसी भी पर्याप्त जटिल C या फॉर्ट्रान कार्यक्रम में कॉमन Lisp के आधे हिस्से का एक ऐड हॉक अनौपचारिक रूप से निर्दिष्ट बग-रहित धीमा कार्यान्वयन होता है।
अगर आप एक कठिन समस्या को हल करने की कोशिश कर रहे हैं, तो सवाल यह नहीं है कि क्या आप एक पर्याप्त शक्तिशाली भाषा का उपयोग करेंगे, बल्कि क्या आप (क) एक शक्तिशाली भाषा का उपयोग करेंगे, (ख) एक के लिए एक de facto इंटरप्रेटर लिखेंगे, या (ग) स्वयं एक मानव संकलक बन जाएंगे। हम पहले से ही इसे Python के उदाहरण में देख रहे हैं, जहां हम प्रभावी रूप से उस कोड का अनुकरण कर रहे हैं जो एक संकलक लेक्सिकल वेरिएबल को लागू करने के लिए उत्पन्न करेगा।
यह प्रथा केवल सामान्य नहीं है, बल्कि संस्थागत भी है। उदाहरण के लिए, OO दुनिया में आप "पैटर्न" के बारे में बहुत कुछ सुनते हैं। मुझे आश्चर्य है कि क्या ये पैटर्न कभी-कभी मामले (ग) के प्रमाण नहीं हैं, मानव संकलक, काम कर रहे हैं। जब मैं अपने कार्यक्रमों में पैटर्न देखता हूं, तो मैं इसे परेशानी का संकेत मानता हूं। एक कार्यक्रम का आकार केवल उस समस्या को दर्शाना चाहिए जिसे इसे हल करने की आवश्यकता है। कोड में कोई अन्य नियमितता, मेरे लिए कम से कम, यह संकेत है कि मैं ऐसे अमूर्तताओं का उपयोग कर रहा हूं जो पर्याप्त शक्तिशाली नहीं हैं - अक्सर यह कि मैं हाथ से कुछ मैक्रो के विस्तार उत्पन्न कर रहा हूं जिसे मुझे लिखने की आवश्यकता है।
नोट्स
IBM 704 CPU रेफ्रिजरेटर के आकार का था, लेकिन बहुत भारी था। CPU का वजन 3150 पाउंड था, और 4K RAM एक अलग बॉक्स में था जिसका वजन 4000 पाउंड था। सबसे बड़े घरेलू रेफ्रिजरेटर में से एक, Sub-Zero 690, का वजन 656 पाउंड है।
स्टीव रसेल ने 1962 में पहले (डिजिटल) कंप्यूटर गेम, स्पेसवार, को भी लिखा।
अगर आप एक नुकीले बालों वाले बॉस को यह बताने की कोशिश करना चाहते हैं कि आप Lisp में सॉफ्टवेयर लिखने दें, तो आप उसे बता सकते हैं कि यह XML है।
यहां अन्य Lisp उपभाषाओं में संचित करने वाले जनरेटर हैं:
Scheme: (define (foo n)
(lambda (i) (set! n (+ n i)) n))
Goo: (df foo (n) (op incf n _)))
Arc: (def foo (n) [++ n _])
एरान गेट की "उद्योग की सर्वश्रेष्ठ प्रथा" के बारे में दुखद कहानी ने मुझे इस सामान्य रूप से गलत तरीके से लागू किए गए वाक्यांश को संबोधित करने के लिए प्रेरित किया।
पीटर नॉर्विग ने पाया कि डिज़ाइन पैटर्न में 23 पैटर्न में से 16 "अदृश्य या सरल" थे Lisp में।
मेरे सवालों के जवाब देने के लिए कई लोगों का धन्यवाद, विभिन्न भाषाओं के बारे में और/या इसके ड्राफ्ट पढ़ने के लिए, जिनमें केन एंडरसन, ट्रेवर ब्लैकवेल, एरान गेट, डैन गिफिन, सारा हार्लिन, जेरमी हाइल्टन, रॉबर्ट मॉरिस, पीटर नॉर्विग, गाई स्टील, और एंटन वैन स्ट्रेटन शामिल हैं। वे व्यक्त की गई किसी भी राय के लिए कोई दोष नहीं उठाते।
संबंधित:
कई लोगों ने इस वार्ता का उत्तर दिया है, इसलिए मैंने उन मुद्दों से निपटने के लिए एक अतिरिक्त पृष्ठ स्थापित किया है जो उन्होंने उठाए हैं: Re: Revenge of the Nerds।
इसने LL1 मेलिंग सूची पर एक व्यापक और अक्सर उपयोगी चर्चा को भी शुरू किया। विशेष रूप से एंटन वैन स्ट्रेटेन द्वारा सेमांटिक संकुचन पर भेजे गए मेल को देखें।
LL1 पर कुछ मेल ने मुझे Succinctness is Power में भाषा शक्ति के विषय में गहराई से जाने के लिए प्रेरित किया।
accumulator generator benchmark के बड़े सेट के मानक कार्यान्वयन एक ही पृष्ठ पर एकत्र किए गए हैं।
Japanese Translation, Spanish Translation, Chinese Translation