लिस्प को क्या अलग बनाता है
दिसंबर 2001 (संशोधित मई 2002)
(यह लेख LL1 मेलिंग सूची पर कुछ सवालों के जवाब में आया था। यह अब Revenge of the Nerds में शामिल है।)
जब मैकार्थी ने 1950 के दशक के अंत में लिस्प को डिजाइन किया, तो यह मौजूदा भाषाओं से एक क्रांतिकारी प्रस्थान था, जिनमें सबसे महत्वपूर्ण Fortran थी।
लिस्प ने नौ नए विचारों को समाहित किया:
1. कंडीशनल। एक कंडीशनल एक इफ-Then-Else कंस्ट्रक्ट है। हम इसे आज सामान्य मानते हैं। इनका आविष्कार मैकार्थी ने लिस्प के विकास के दौरान किया था। (उस समय Fortran में केवल एक कंडीशनल goto था, जो अंतर्निहित हार्डवेयर में ब्रांच इंस्ट्रक्शन पर बारीकी से आधारित था।) मैकार्थी, जो Algol समिति में थे, ने कंडीशनल को Algol में शामिल करवाया, जहाँ से वे अधिकांश अन्य भाषाओं में फैल गए।
2. एक फंक्शन टाइप। लिस्प में, फ़ंक्शन प्रथम श्रेणी के ऑब्जेक्ट होते हैं - वे पूर्णांक, स्ट्रिंग आदि की तरह एक डेटा प्रकार होते हैं, और उनका एक शाब्दिक प्रतिनिधित्व होता है, उन्हें चर में संग्रहीत किया जा सकता है, उन्हें तर्कों के रूप में पास किया जा सकता है, और इसी तरह।
3. रिकर्सन। रिकर्सन लिस्प से पहले एक गणितीय अवधारणा के रूप में मौजूद था, बेशक, लेकिन लिस्प इसे समर्थन देने वाली पहली प्रोग्रामिंग भाषा थी। (यह बहस योग्य रूप से फ़ंक्शन को प्रथम श्रेणी ऑब्जेक्ट बनाने में निहित है।)
4. चर की एक नई अवधारणा। लिस्प में, सभी चर प्रभावी रूप से पॉइंटर होते हैं। मान वे होते हैं जिनके प्रकार होते हैं, चर नहीं, और चर को असाइन या बाइंड करने का मतलब पॉइंटर्स को कॉपी करना है, न कि वे जिस चीज़ को इंगित करते हैं।
5. गार्बेज-कलेक्शन।
6. एक्सप्रेशन से बने प्रोग्राम। लिस्प प्रोग्राम एक्सप्रेशन के पेड़ होते हैं, जिनमें से प्रत्येक एक मान लौटाता है। (कुछ लिस्प में एक्सप्रेशन कई मान लौटा सकते हैं।) यह Fortran और अधिकांश बाद की भाषाओं के विपरीत है, जो एक्सप्रेशन और स्टेटमेंट के बीच अंतर करती हैं।
Fortran में यह अंतर स्वाभाविक था क्योंकि (आश्चर्य नहीं कि एक भाषा में जहाँ इनपुट फॉर्मेट पंच कार्ड था) भाषा लाइन-उन्मुख थी। आप स्टेटमेंट को नेस्ट नहीं कर सकते थे। और इसलिए जबकि गणित के काम करने के लिए आपको एक्सप्रेशन की आवश्यकता थी, किसी और चीज़ को मान लौटाने का कोई मतलब नहीं था, क्योंकि उसके लिए कुछ भी इंतजार नहीं कर रहा था।
ब्लॉक-स्ट्रक्चर्ड भाषाओं के आगमन के साथ यह सीमा समाप्त हो गई, लेकिन तब तक बहुत देर हो चुकी थी। एक्सप्रेशन और स्टेटमेंट के बीच का अंतर स्थापित हो गया था। यह Fortran से Algol में और फिर उनके दोनों वंशजों में फैल गया।
जब कोई भाषा पूरी तरह से एक्सप्रेशन से बनी होती है, तो आप एक्सप्रेशन को कैसे भी कंपोज़ कर सकते हैं। आप कह सकते हैं (या तो Arc सिंटैक्स का उपयोग करके)
(if foo (= x 1) (= x 2))
या
(= x (if foo 1 2))
7. एक सिंबल टाइप। सिंबल स्ट्रिंग से इस मायने में भिन्न होते हैं कि आप एक पॉइंटर की तुलना करके समानता का परीक्षण कर सकते हैं।
8. प्रतीकों के पेड़ों का उपयोग करके कोड के लिए एक नोटेशन।
9. पूरी भाषा हमेशा उपलब्ध। रीड-टाइम, कंपाइल-टाइम और रनटाइम के बीच कोई वास्तविक अंतर नहीं है। आप पढ़ते समय कोड को कंपाइल या रन कर सकते हैं, कंपाइल करते समय कोड को पढ़ या रन कर सकते हैं, और Emacs जैसे प्रोग्रामों में लिस्प के विस्तार भाषा के रूप में उपयोग के आधार पर रनटाइम पर कोड को कंपाइल कर सकते हैं; और रनटाइम पर पढ़ना प्रोग्रामों को एस-एक्सप्रेशन का उपयोग करके संवाद करने में सक्षम बनाता है, एक विचार जिसे हाल ही में XML के रूप में फिर से आविष्कार किया गया है।
जब लिस्प का आविष्कार पहली बार हुआ था, तो ये सभी विचार सामान्य प्रोग्रामिंग अभ्यास से बहुत दूर थे, जो 1950 के दशक के अंत में उपलब्ध हार्डवेयर द्वारा काफी हद तक निर्धारित था।
समय के साथ, डिफ़ॉल्ट भाषा, लोकप्रिय भाषाओं के उत्तराधिकार में सन्निहित, धीरे-धीरे लिस्प की ओर विकसित हुई है। 1-5 अब व्यापक हैं। 6 मुख्यधारा में दिखाई देने लगा है। पायथन में 7 का एक रूप है, हालांकि इसके लिए कोई सिंटैक्स नहीं लगता है। 8, जो (9 के साथ) वह है जो लिस्प मैक्रोज़ को संभव बनाता है, अब तक लिस्प के लिए अद्वितीय है, शायद इसलिए कि (ए) इसके लिए उन कोष्ठकों की आवश्यकता होती है, या कुछ बस उतना ही बुरा है, और (बी) यदि आप शक्ति की वह अंतिम वृद्धि जोड़ते हैं, तो आप अब एक नई भाषा का आविष्कार करने का दावा नहीं कर सकते हैं, बल्कि केवल लिस्प के एक नए बोली को डिजाइन करने का दावा कर सकते हैं; -)
हालांकि आज के प्रोग्रामर के लिए उपयोगी है, लिस्प को अन्य भाषाओं द्वारा अपनाए गए यादृच्छिक व्यय से इसके विचलन के संदर्भ में वर्णित करना अजीब है। शायद मैकार्थी ने इसे इस तरह से नहीं सोचा था। लिस्प को Fortran की गलतियों को ठीक करने के लिए डिज़ाइन नहीं किया गया था; यह गणना को स्वयंसिद्ध करने के प्रयास के उप-उत्पाद के रूप में अधिक आया।