कुछ समय पहले (लगभग तीन साल) मैंने लिस्प पर एक पाठ्यपुस्तक पढ़ने का फैसला किया। किसी भी विशिष्ट उद्देश्य के बिना, बस सामान्य विकास और विदेशी के साथ वार्ताकारों को झटका देने की क्षमता के लिए (एक बार ऐसा लगता है, यह भी काम किया)।
लेकिन करीब से निरीक्षण करने पर, लिस्प वास्तव में शक्तिशाली, लचीला और, काफी हद तक, रोजमर्रा की जिंदगी में उपयोगी साबित हुआ। सभी छोटे स्वचालन कार्य लिस्प में लिपियों के लिए जल्दी से चले गए, और अधिक जटिल लोगों के स्वचालन के अवसर भी थे।
यहां यह ध्यान दिया जाना चाहिए कि "स्वचालन क्षमता" से मेरा मतलब ऐसी स्थिति से है जहां किसी कार्यक्रम को लिखने और डिबग करने का कुल समय उसी कार्य को हल करने में लगने वाले समय से कम है।
पॉल ग्राहम ने एक से अधिक लेख और यहां तक कि लिस्प के लाभों के बारे में एक किताब भी लिखी है। इस लेखन के समय, लिस्प TOIBE रैंकिंग में 33 वें स्थान पर है (मृत डेल्फी की तुलना में तीन बार मृत)। सवाल उठता है: अगर भाषा इतनी सुविधाजनक है तो छोटी क्यों है? लगभग दो वर्षों के उपयोग ने कारणों के कुछ संकेत दिए।
कमियों
1. साझा डेटा संरचनाएँएक अवधारणा जो आपको कार्यात्मक कार्यक्रमों को अनुकूलित करने की अनुमति देती है, लेकिन अनिवार्य में सूक्ष्म त्रुटियों से भरा है। एक बाहरी डेटा संरचना के लिए आकस्मिक क्षति की संभावना जब एक चर को संशोधित किया जाता है जिसमें संरचना के साथ कोई दृश्य संबंध नहीं होता है, तो प्रोग्रामर को पर्दे के पीछे क्या हो रहा है, इसकी निरंतर निगरानी करने और उपयोग किए जाने वाले प्रत्येक फ़ंक्शन (सिस्टम और उपयोगकर्ता दोनों) के आंतरिक कार्यान्वयन को जानने की आवश्यकता होती है। सबसे आश्चर्यजनक बात एक फ़ंक्शन के शरीर को उसकी वापसी मूल्य को संशोधित करके नुकसान पहुंचाने की क्षमता है।
2. इनकैप्सुलेशन की कमीहालांकि एक पैकेज की अवधारणा मौजूद है, इसका डेल्फी में एडीए या
यूनिट में
पैकेज से कोई लेना-देना नहीं है। कोई भी कोड किसी भी पैकेज (सिस्टम वाले को छोड़कर) में कुछ भी जोड़ सकता है। कोई भी कोड
:: ऑपरेटर का उपयोग करके किसी भी पैकेज से कुछ भी निकाल सकता है।
3. हापाजार्ड संक्षिप्तMAPCAN और MAPCON में क्या अंतर है? SETQ में, अंतिम अक्षर Q क्यों? भाषा की उम्र को देखते हुए, आप इस स्थिति के कारणों को समझ सकते हैं, लेकिन मैं भाषा को थोड़ा साफ करना चाहता हूं।
4. बहुरूपतायह कमी अप्रत्यक्ष रूप से लिस्प से संबंधित है और मुख्य रूप से मेरे द्वारा उपयोग किए जाने वाले कार्यान्वयन की चिंता है - स्टीलबैंक कॉमन लिस्प। आम लिस्प मल्टीथ्रेडिंग का समर्थन नहीं करता है। SBCL द्वारा प्रदान किए गए कार्यान्वयन का उपयोग करने का प्रयास विफल रहा।
इस तरह के एक सुविधाजनक उपकरण को मना करना एक दया है, लेकिन असंतोष धीरे-धीरे जमा होता है।
समाधान के लिए खोजें
सबसे पहले आप लिस्प पेज पर विकिपीडिया पर जा सकते हैं। "बोलियों" अनुभाग का निरीक्षण करें। प्रत्येक के लिए एक संक्षिप्त परिचय पढ़ें। और महसूस करें कि सभी मार्करों का स्वाद और रंग अलग-अलग है।
यदि आप कुछ करना चाहते हैं, तो आपको इसे स्वयं करने की आवश्यकता है
- जीन बैप्टिस्ट इमैनुएल सोर्ग
आइए थोड़ा अडा, बहुत डेल्फी और इसमें ओबेरॉन की एक बूंद को जोड़कर अपना खुद का सही लिस्प बनाने की कोशिश करें। हम परिणामस्वरूप मिश्रण फॉक्स कहते हैं।
मूल अवधारणाएँ
1. कोई संकेत नहींPROBLEM-1 के खिलाफ लड़ाई में, मूल्यों को कॉपी करके सभी ऑपरेशन किए जाने चाहिए। कोड में या प्रिंट करते समय डेटा संरचना के प्रकार से, इसके सभी गुण, बाहरी और आंतरिक कनेक्शन पूरी तरह से दिखाई देने चाहिए।
2. मॉड्यूल जोड़ेंसमस्या -2 के खिलाफ लड़ाई के हिस्से के रूप में, हम एडा से बयानों का
उपयोग और
उपयोग के साथ पैकेज आयात
करते हैं । इस प्रक्रिया में, हम लिस्प प्रतीकों के लिए अत्यधिक जटिल आयात / छायांकन योजना को छोड़ देते हैं।
(package - ( ) () ())
(with -)
(use -)
3. संक्षिप्त रूपसबसे आम और आम चरित्र अभी भी संक्षिप्त होंगे, लेकिन ज्यादातर सबसे स्पष्ट:
कास्ट ,
संस्करण । स्वरूपित आउटपुट फ़ंक्शन - एफएमटी में कमी की आवश्यकता होती है, क्योंकि यह अक्सर अभिव्यक्तियों के अंदर पाया जाता है।
Elt - एक तत्व लेना - कॉमन लिस्प से लीक हुआ और जड़ लिया, हालांकि इसे कम करने की कोई आवश्यकता नहीं है।
4. केस-असंवेदनशील पहचानकर्तामेरा मानना है कि सही भाषा (और फ़ाइल सिस्टम) {$ HOLYWAR +} केस-असंवेदनशील {$ HOLYWAR-} होनी चाहिए ताकि इसके दिमाग को एक बार फिर से रैक न करें।
5. रूसी कीबोर्ड लेआउट के साथ उपयोग में आसानीसिंटेक्स Lisi हर संभव तरीके से उन पात्रों के उपयोग से बचाती है जो लेआउट में से किसी एक में उपलब्ध नहीं हैं। कोई वर्ग या घुंघराले ब्रेसिज़ नहीं। नहीं #, ~, &, <,>, | संख्यात्मक शाब्दिक पढ़ते समय, अल्पविराम और अवधि दोनों को दशमलव विभाजक माना जाता है।
6. विस्तारित वर्णमालाSBCL के बारे में अच्छी चीजों में से एक कोड में UTF-8 थी। स्थिरांक BEAR, VODKA और BALALAYKA को घोषित करने की क्षमता आवेदन कोड के लेखन को बहुत सरल करती है। Ability, Ψ, और The सम्मिलित करने की क्षमता कोड में सूत्रों को अधिक दृश्य बनाती है। यद्यपि सैद्धांतिक रूप से किसी भी यूनिकोड वर्ण का उपयोग करने की संभावना है, लेकिन उनके साथ काम करने की शुद्धता की गारंटी देना मुश्किल है (बल्कि मुश्किल से आलस्य)। हम खुद को सिरिलिक, लैटिन और ग्रीक तक सीमित रखते हैं।
7. संख्यात्मक शाब्दिकयह मेरे लिए सबसे उपयोगी भाषा विस्तार है।
10_000
बाद वाला विकल्प मुझे सबसे अधिक सौंदर्यवादी लगता है, लेकिन यह सबसे लोकप्रिय है।
8. चक्रलिस्प में चक्र गैर-मानक और बहुत गड़बड़ हैं। न्यूनतम मानक सेट के लिए सरलीकृत करें।
(for i 5
लूप वेरिएबल बाहर दिखाई नहीं देता है।
(while )
9. गोटोबहुत आवश्यक ऑपरेटर नहीं है, लेकिन इसके बिना संरचनात्मक प्रोग्रामिंग के नियमों की उपेक्षा प्रदर्शित करना मुश्किल है।
(block : (goto :))
10. गुंजाइश का एकीकरणलिस्प में दो अलग-अलग प्रकार के स्कोप हैं: TOPLEVEL और स्थानीय। तदनुसार, चर घोषित करने के दो अलग-अलग तरीके हैं।
(defvar A 1) (let ((a 1)) …)
फॉक्स में स्क्रिप्ट के शीर्ष स्तर पर और संकुल सहित स्थानीय क्षेत्रों में केवल एक ही विधि का उपयोग किया जाता है।
(var A 1)
यदि आप दायरे को सीमित करना चाहते हैं, तो ऑपरेटर का उपयोग करें
(block (var A 1) (set A 2) (fmt nil A))
लूप का शरीर निहित ब्लॉक स्टेटमेंट (फ़ंक्शन / प्रक्रिया के शरीर की तरह) में निहित है। लूप में घोषित सभी चर पुनरावृत्ति के अंत में नष्ट हो जाते हैं।
11. एकल-स्लॉट वर्णलिस्प में, फ़ंक्शन विशेष ऑब्जेक्ट होते हैं और एक विशेष प्रतीक स्लॉट में संग्रहीत होते हैं। एक एकल चरित्र एक साथ एक चर, फ़ंक्शन और संपत्ति सूची को संग्रहीत कर सकता है। एक लोमड़ी में, प्रत्येक वर्ण केवल एक अर्थ के साथ जुड़ा हुआ है।
12. सुविधाजनक ईएलटीलिस्प में जटिल संरचना के एक तत्व तक विशिष्ट पहुंच इस तरह दिखती है
(elt (slot-value (elt 1) '-2) 3)
फॉक्स में एक एकीकृत ईएलटी ऑपरेटर है जो किसी भी मिश्रित प्रकार (सूची, तार, रिकॉर्ड, बाइट सरणियों, हैश टेबल) के तत्वों तक पहुंच प्रदान करता है।
(elt 1 \-2 3)
लिस्प में मैक्रो के साथ समान कार्यक्षमता भी प्राप्त की जा सकती है
(defmacro field (object &rest f) " . (field *object* 0 :keyword symbol \"string\") . plist. ( ) . ." (if f (symbol-macrolet ((f0 (elt f 0))(rest (subseq f 1))) (cond ((numberp f0) `(field (elt ,object ,f0) ,@rest)) ((keywordp f0) `(field (getf ,object ,f0) ,@rest)) ((stringp f0) `(field (cdr (assoc ,f0 ,object :test 'equal)) ,@rest)) ((and (listp f0) (= 2 (length f0))) `(field (,(car f0) ,(cadr f0) ,object) ,@rest)) ((symbolp f0) `(field (,f0 ,object) ,@rest)) (t `(error " ")))) object))
13. सबरूटीन पैरामीटर स्थानांतरण मोड का प्रतिबंधलिस्प में पैरामीटर ट्रांसफर के कम से कम पांच मोड हैं: अनिवार्य,
और वैकल्पिक ,
और बाकी ,
और कुंजी ,
और पूरे और उनके मनमाने संयोजन की अनुमति है। वास्तव में, अधिकांश संयोजन अजीब प्रभाव देते हैं।
फॉक्स में इसे आवश्यक मापदंडों और संयोजन में से किसी एक का उपयोग करने की अनुमति है
: कुंजी ,: वैकल्पिक,: झंडा ,: बाकी ।
14. बहु तबहुस्तरीय कार्यक्रमों के लेखन को अत्यंत सरल बनाने के लिए, स्मृति पृथक्करण की अवधारणा को अपनाया गया था। जब एक धागा पैदा होता है, तो नए धागे के लिए उपलब्ध सभी चर कॉपी किए जाते हैं। इन चरों के सभी संदर्भों को प्रतियों के संदर्भ से बदल दिया जाता है। धाराओं के बीच सूचना हस्तांतरण केवल संरक्षित वस्तुओं के माध्यम से या पूरा होने पर स्ट्रीम द्वारा लौटाए गए परिणाम के माध्यम से संभव है।
संरक्षित वस्तुओं में हमेशा परमाणु संचालन सुनिश्चित करने के लिए महत्वपूर्ण खंड होते हैं। महत्वपूर्ण खंडों में लॉगिंग स्वचालित है - भाषा में इसके लिए कोई अलग ऑपरेटर नहीं हैं। संरक्षित ऑब्जेक्ट्स में शामिल हैं: संदेश कतार, कंसोल और फ़ाइल विवरणक।
बहु-थ्रेडेड डिस्प्ले फ़ंक्शन के साथ थ्रेड्स बनाना संभव है
(map-th (function (x) …) --)
मैप-वें स्वचालित रूप से सिस्टम में प्रोसेसर की संख्या के बराबर थ्रेड्स की संख्या शुरू करता है (या यदि आपके अंदर इंटेल है तो दो बार)। एक पुनरावर्ती कॉल में, बाद के नक्शे-वें कॉल एक ही धागे में काम करते हैं।
इसके अतिरिक्त, एक अंतर्निहित थ्रेड फ़ंक्शन है जो एक अलग थ्रेड में एक प्रक्रिया / फ़ंक्शन को निष्पादित करता है।
15. अनिवार्य संहिता में कार्यात्मक सफाईफॉक्स में कार्यात्मक प्रोग्रामिंग और प्रक्रियात्मक प्रक्रियाओं के लिए कार्य हैं। फ़ंक्शन कीवर्ड का उपयोग करके घोषित की गई दिनचर्या साइड इफेक्ट्स की अनुपस्थिति और बाहरी कारकों से परिणाम की स्वतंत्रता की आवश्यकताओं के अधीन है।
अचेतन
लिस्प की कुछ दिलचस्प विशेषताएं कम प्राथमिकता के कारण अधूरी रह गईं।
1. सामान्यीकृत विधियाँडिफेनरोजिक / डिफमेथोड के साथ कार्यों को ओवरलोड करने की क्षमता।
2. वंशानुक्रम3. निर्मित डिबगरजब कोई अपवाद होता है, तो लिस्प दुभाषिया डिबग मोड पर स्विच करता है।
4. यूएफएफआईअन्य भाषाओं में लिखे गए मॉड्यूल को जोड़ने के लिए इंटरफ़ेस।
5. BIGNUMमनमाना बिट गहराई समर्थन
त्यागलिस्प की कुछ विशेषताओं पर विचार किया गया है और उन्हें बेकार / हानिकारक माना गया है।
1. तरीकों का निर्देशित संयोजनजब किसी विधि को कक्षा के लिए बुलाया जाता है, तो मूल विधियों का संयोजन किया जाता है और संयोजन नियमों को बदलना संभव है। विधि का अंतिम व्यवहार खराब अनुमान के साथ लगता है।
2. विश्राम करता हैअपवाद हैंडलर प्रोग्राम की स्थिति में परिवर्तन कर सकता है और अपवाद उत्पन्न करने वाले कोड को एक पुनरारंभ कमांड भेज सकता है। फ़ंक्शन का फ़ंक्शन फ़ंक्शन से फ़ंक्शन पर स्विच करने के लिए GOTO ऑपरेटर का उपयोग करने के समान है।
3. रोमन खातालिस्प उस नंबर सिस्टम का समर्थन करता है, जो अपनी उपस्थिति से कुछ समय पहले पुराना है।
के उपयोग
यहाँ कुछ सरल कोड उदाहरण हैं।
(function crc8 (data :optional seed) (var result (if-nil seed 0)) (var s_data data) (for bit 8 (if (= (bit-and (bit-xor result s_data) $01) 0) (set result (shift result -1 8)) (else (set result (bit-xor result $18)) (set result (shift result -1 8)) (set result (bit-or result $80)))) (set s_data (shift s_data -1 8))) result)
कार्यान्वयन
दुभाषिया डेल्फी में लिखा गया है (संगतता मोड में FreePascal)। यह विंडोज और लिनक्स 32 और 64 बिट्स के तहत, लाजर 1.6.2 और उच्चतर में बनाया गया है। बाहरी निर्भरता की, libmysql.dll की आवश्यकता है। इसमें लगभग 15_000..20_000 रेखाएँ हैं। विभिन्न प्रयोजनों के लिए लगभग 200 अंतर्निहित कार्य हैं (कुछ आठ बार ओवरलोड हैं)।
यहां स्टोर कियाडायनामिक टाइपिंग के लिए समर्थन एक तुच्छ तरीके से किया जाता है - सभी संसाधित डेटा प्रकारों को एक ही TValue वर्ग के वारिस द्वारा दर्शाया जाता है।
लिस्प के लिए सबसे महत्वपूर्ण प्रकार - सूची है, जैसा कि डेल्फी में प्रथागत है, एक ऐसा वर्ग जिसमें टाइप टीवील्यू की वस्तुओं का एक गतिशील सरणी है। इस प्रकार के लिए, CopyOnWrite तंत्र कार्यान्वित किया जाता है।
स्मृति प्रबंधन संदर्भ गिनती के आधार पर स्वचालित है। पुनरावर्ती संरचनाओं के लिए, संरचना में सभी लिंक एक साथ गिने जाते हैं। मेमोरी रिलीज़ तुरंत शुरू होती है जब चर दायरे से बाहर निकलते हैं। कूड़ा उठाने वाले के देरी से शुरू होने की कोई व्यवस्था नहीं है।
एक्सेप्शन हैंडलिंग डेल्फी में निर्मित एक तंत्र पर काम करता है। इस प्रकार, दुभाषिया के कोड में होने वाली त्रुटियों को फॉक्स पर निष्पादन योग्य कोड द्वारा संसाधित किया जा सकता है।
प्रत्येक ऑपरेटर या बिल्ट-इन लिसी फ़ंक्शन इंटरप्रेटर कोड में एक विधि या फ़ंक्शन के रूप में लागू किया जाता है। स्क्रिप्ट को क्रियान्वयन के पारस्परिक रूप से पुनरावर्ती कॉल द्वारा निष्पादित किया जाता है। दुभाषिया कोड और स्क्रिप्ट में एक सामान्य कॉल स्टैक होता है।
स्क्रिप्ट चर स्वतंत्र रूप से गतिशील मेमोरी में संग्रहीत होते हैं। प्रत्येक उपयोगकर्ता-परिभाषित फ़ंक्शन के पास चर संदर्भों को संग्रहीत करने के लिए अपना स्वयं का स्टैक होता है, जो शीर्ष-स्तरीय स्टैक या माता-पिता के कार्यों के ढेर से स्वतंत्र होता है।
विशेष रूप से कठिनाई संरचनात्मक तत्वों के लिए असाइनमेंट ऑपरेटर (सेट) का कार्यान्वयन है। आवश्यक तत्व के लिए सूचक की सीधे गणना करने से लिंक के खतरों का खतरा होता है, क्योंकि एलआईएस सिंटैक्स आवश्यक तत्व की गणना के दौरान संरचना को संशोधित करने पर रोक नहीं लगाता है। एक समझौता समाधान के रूप में, एक "चेन पॉइंटर" को लागू किया जाता है - एक चर के संदर्भ में एक वस्तु और संरचना के भीतर पथ को इंगित करने के लिए संख्यात्मक सूचक का एक सरणी। इस तरह के एक पॉइंटर को लटकने वाले लिंक की समस्या के लिए भी अतिसंवेदनशील है, लेकिन विफलता की स्थिति में यह एक सार्थक त्रुटि संदेश उत्पन्न करता है।
विकास के उपकरण
1. सांत्वना2. पाठ संपादकसिंटैक्स हाइलाइटिंग और F9 में एक संपादन योग्य स्क्रिप्ट को चलाने की क्षमता से लैस है।

निष्कर्ष
वर्तमान स्थिति में, परियोजना उन समस्याओं को हल करती है जिनके लिए इसकी कल्पना की गई थी, और उन्हें आगे सक्रिय विकास की आवश्यकता नहीं है। मौजूद कई खामियां काम को प्रभावित नहीं करती हैं।