क्या एक सांख्यिकीय-टाइप पूर्ण लिस्प संस्करण संभव है? यह भी कुछ इस तरह मौजूद है के लिए समझ में आता है? मेरा मानना है कि लिस्प भाषा का एक गुण इसकी परिभाषा की सरलता है। क्या स्थैतिक टाइपिंग इस मूल सिद्धांत से समझौता करेगा?
क्या एक सांख्यिकीय-टाइप पूर्ण लिस्प संस्करण संभव है? यह भी कुछ इस तरह मौजूद है के लिए समझ में आता है? मेरा मानना है कि लिस्प भाषा का एक गुण इसकी परिभाषा की सरलता है। क्या स्थैतिक टाइपिंग इस मूल सिद्धांत से समझौता करेगा?
जवाबों:
हां, यह बहुत संभव है, हालांकि एक मानक एचएम-शैली प्रकार प्रणाली आमतौर पर सबसे मुहावरेदार लिस्प / योजना कोड के लिए गलत विकल्प है। हाल की भाषा के लिए टाइप किया गया रैकेट देखें जो स्थिर टाइपिंग के साथ "पूर्ण लिस्प" (योजना की तरह, वास्तव में) है।
Sexpr
।
coerce :: a->b
eval के संदर्भ में लिख सकता हूं । प्रकार की सुरक्षा कहाँ है?
eval
तो आपको परिणाम देखने के लिए परिणाम की जांच करने की आवश्यकता होती है, जो टाइप किए गए रैक में नया नहीं है (एक फ़ंक्शन के रूप में समान सौदा जो एक यूनियन प्रकार String
और लेता है Number
)। यह देखने का एक निहित तरीका है कि यह किया जा सकता है तथ्य यह है कि आप एचएम-स्टेटिकली टाइप की गई भाषा में गतिशील रूप से टाइप की गई भाषा को लिख और उपयोग कर सकते हैं।
यदि आप चाहते थे कि एक पूरी तरह से टाइप की गई भाषा जो लिस्प की तरह दिखे , तो आप एक सार वाक्यविन्यास ट्री को परिभाषित करके आसानी से कर सकते हैं जो आपकी भाषा का प्रतिनिधित्व करता है और फिर उस एएसटी को एस-एक्सप्रेशंस में मैप कर सकता है। हालांकि, मुझे नहीं लगता कि मैं परिणाम को लिस्प कहूंगा।
यदि आप कुछ ऐसा चाहते हैं जो वास्तव में सिंटैक्स के अलावा लिस्प-वाई विशेषताओं है, तो यह एक सांख्यिकीय रूप से टाइप की गई भाषा के साथ करना संभव है। हालांकि, लिस्प की कई विशेषताएं हैं जो बहुत उपयोगी स्थिर टाइपिंग से बाहर निकलना मुश्किल हैं। वर्णन करने के लिए, आइए सूची संरचना पर एक नज़र डालें, जिसे कॉन्स कहा जाता है , जो लिस्प का प्राथमिक बिल्डिंग ब्लॉक बनाती है।
विपक्ष को एक सूची (1 2 3)
कहना , हालांकि एक जैसा दिखता है, एक मिथ्या नाम है। उदाहरण के लिए, यह सांख्यिकीय रूप से टाइप की गई सूची की तुलना में बिल्कुल नहीं है, जैसे कि C ++ की std::list
या हास्केल की सूची। वे एकल-आयामी लिंक्ड सूची हैं जहां सभी कोशिकाएं एक ही प्रकार की हैं। लिस्प खुशी से अनुमति देता है (1 "abc" #\d 'foo)
। इसके अलावा, भले ही आप सूचियों के सूचियों को कवर करने के लिए अपनी स्थिर-टाइप की गई सूचियों का विस्तार करते हैं, इन वस्तुओं के प्रकार के लिए आवश्यक है कि सूची का प्रत्येक तत्व एक सबलिस्ट हो। आप ((1 2) 3 4)
उनमें कैसे प्रतिनिधित्व करेंगे?
लिस्प की पत्तियां एक बाइनरी ट्री बनाती हैं, जिसमें पत्तियां (परमाणु) और शाखाएं (कंस) होती हैं। इसके अलावा, इस तरह के पेड़ की पत्तियों में कोई भी परमाणु (गैर-विपक्ष) लिस्प प्रकार हो सकता है! इस संरचना का लचीलापन वह है जो लिस्प को प्रतीकात्मक संगणना, एएसटीएस और स्वयं लिस्प कोड को बदलने में बहुत अच्छा बनाता है!
तो आप इस तरह की संरचना को सांख्यिकीय रूप से टाइप की हुई भाषा में कैसे प्रस्तुत करेंगे? आइए इसे हास्केल में आज़माएं, जिसमें एक अत्यंत शक्तिशाली और सटीक स्थैतिक प्रकार प्रणाली है:
type Symbol = String
data Atom = ASymbol Symbol | AInt Int | AString String | Nil
data Cons = CCons Cons Cons
| CAtom Atom
आपकी पहली समस्या एटम टाइप का दायरा बनने जा रहा है। स्पष्ट रूप से, हमने उन सभी प्रकार की वस्तुओं को ढंकने के लिए पर्याप्त लचीलेपन का एटम प्रकार नहीं उठाया है, जिन्हें हम समेटना चाहते हैं। एटम डेटा संरचना को ऊपर सूचीबद्ध करने की कोशिश करने के बजाय (जिसे आप स्पष्ट रूप से भंगुर देख सकते हैं), मान लें कि हमारे पास एक जादुई प्रकार का वर्ग था Atomic
जो उन सभी प्रकारों को अलग करता था जिन्हें हम परमाणु बनाना चाहते थे। तब हम कोशिश कर सकते हैं:
class Atomic a where ?????
data Atomic a => Cons a = CCons Cons Cons
| CAtom a
लेकिन यह काम नहीं करेगा क्योंकि यह पेड़ में सभी परमाणुओं को एक ही प्रकार का होना चाहिए । हम चाहते हैं कि वे पत्ती से पत्ती तक भिन्न हो सकें। एक बेहतर दृष्टिकोण के लिए हास्केल के अस्तित्व की मात्रा का उपयोग करने की आवश्यकता होती है :
class Atomic a where ?????
data Cons = CCons Cons Cons
| forall a. Atomic a => CAtom a
लेकिन अब आप इस मामले पर आते हैं। आप इस तरह की संरचना में परमाणुओं के साथ क्या कर सकते हैं? उनके पास क्या संरचना है जो सामान्य रूप से मॉडलिंग की जा सकती है Atomic a
? आप किस प्रकार की सुरक्षा की गारंटी देते हैं? ध्यान दें कि हमने अपने प्रकार वर्ग में कोई फ़ंक्शन नहीं जोड़ा है, और इसका एक अच्छा कारण है: परमाणुओं में लिस्प में कुछ भी साझा नहीं होता है। लिस्प में उनके सुपरपाइप को बस t
(यानी शीर्ष) कहा जाता है ।
इनका उपयोग करने के लिए, आपको तंत्र के साथ गतिशील रूप से एक परमाणु के मूल्य के साथ कुछ करना होगा जो आप वास्तव में उपयोग कर सकते हैं। और उस बिंदु पर, आपने मूल रूप से अपनी वैधानिक रूप से टाइप की गई भाषा के भीतर एक गतिशील टाइप सबसिस्टम लागू किया है! (कोई भी मदद नहीं कर सकता है लेकिन ग्रीनस्पून के प्रोग्रामिंग के दसवें नियम के लिए एक संभावित कोरोलरी नोट कर सकता है ।)
ध्यान दें कि हास्केल केवल एक प्रकार के साथ इस तरह के एक गतिशील सबसिस्टम के लिए समर्थन प्रदान करता है , जो हमारे वर्ग को बदलने के लिए Obj
एक Dynamic
प्रकार और एक टाइप करने योग्य वर्ग के साथ संयोजन के रूप में उपयोग किया जाता है Atomic
, जो मनमाने ढंग से मूल्यों को उनके प्रकारों के साथ संग्रहीत करने की अनुमति देता है, और उन प्रकारों से स्पष्ट रूप से जबरदस्ती करता है। इस तरह की प्रणाली का उपयोग करने के लिए आपको अपनी पूरी व्यापकता में लिस्प विपक्ष संरचनाओं के साथ काम करने की आवश्यकता होगी।
आप जो भी कर सकते हैं वह दूसरे तरीके से कर सकते हैं, और एक अनिवार्य रूप से टाइप की गई भाषा के भीतर एक सांख्यिकीय टाइप किए गए सबसिस्टम को एम्बेड कर सकते हैं। यह आपको अपने प्रोग्राम के उन हिस्सों के लिए स्थैतिक प्रकार की जाँच का लाभ देता है जो अधिक कठोर प्रकार की आवश्यकताओं का लाभ उठा सकते हैं। उदाहरण के लिए, यह सटीक प्रकार की जाँच के सीएमयूसीएल के सीमित रूप में लिया गया दृष्टिकोण प्रतीत होता है ।
अंत में, गतिशील और सांख्यिकीय रूप से टाइप किए गए दो अलग-अलग सबसिस्टम होने की संभावना है, जो दोनों के बीच संक्रमण को नेविगेट करने में मदद करने के लिए अनुबंध-शैली प्रोग्रामिंग का उपयोग करते हैं। इस तरह से भाषा लिस्प के usages को समायोजित कर सकती है जहाँ स्थैतिक प्रकार की जाँच एक मदद से अधिक बाधा होगी, साथ ही साथ जहाँ स्थिर प्रकार की जाँच लाभप्रद होगी, का उपयोग करती है। यह टाइप्ड रैकेट द्वारा लिया गया दृष्टिकोण है , जैसा कि आप टिप्पणियों से देखेंगे।
(Listof Integer)
और (Listof Any)
। जाहिर है, आपको बाद में बेकार होने का संदेह होगा क्योंकि आप प्रकार के बारे में कुछ नहीं जानते हैं, लेकिन टीआर में, आप बाद में उपयोग कर सकते हैं (if (integer? x) ...)
और सिस्टम को पता चल जाएगा कि x
1 शाखा में एक इंटेगर है।
dynamic
प्रकार स्थिर भाषाओं में लोकप्रिय हो रहे हैं, गतिशील प्रकार की भाषाओं के कुछ लाभ प्राप्त करने के लिए एक तरह के वर्कअराउंड के रूप में, इन मूल्यों के सामान्य ट्रेडऑफ़ के साथ एक तरह से लिपटे जा रहे हैं जो प्रकारों की पहचान करता है। लेकिन यहां भी टाइप किए गए रैकेट भाषा के भीतर इसे सुविधाजनक बनाने के लिए बहुत अच्छा काम कर रहे हैं - टाइप चेकर प्रकारों के बारे में अधिक जानने के लिए विधेय की घटनाओं का उपयोग करता है। उदाहरण के लिए, रैकेट पृष्ठ पर टाइप किए गए उदाहरण को देखें और देखें कि string?
स्ट्रिंग्स की एक सूची के लिए स्ट्रिंग्स और संख्याओं की "कम" कैसे की जाती है।
मेरा जवाब, बिना उच्च आत्मविश्वास के शायद है । यदि आप उदाहरण के लिए, SML जैसी भाषा को देखते हैं, और लिस्प के साथ तुलना करते हैं, तो प्रत्येक का कार्यात्मक कोर लगभग समान है। नतीजतन, ऐसा नहीं लगता है कि आपको लिस्प के मूल में फ़ंक्शन टाइपिंग (फ़ंक्शन एप्लिकेशन और प्राइमर वैल्यूज़) के लिए किसी प्रकार का स्टेटिक टाइप करने में बहुत परेशानी होगी।
आपका प्रश्न पूर्ण रूप से कहता है , और जहां मुझे कुछ समस्या आ रही है वह कोड-ए-डेटा दृष्टिकोण है। प्रकार अभिव्यक्ति की तुलना में अधिक सार स्तर पर मौजूद हैं। लिस्प में यह अंतर नहीं है - संरचना में सब कुछ "सपाट" है। यदि हम कुछ अभिव्यक्ति E: T पर विचार करते हैं (जहाँ T अपने प्रकार का कुछ निरूपण है), और फिर हम इस अभिव्यक्ति को सादा ol 'डेटा मानते हैं, तो यहाँ T का प्रकार क्या है? खैर, यह एक तरह का है! एक प्रकार एक उच्च, आदेश प्रकार है, तो चलो आगे बढ़ते हैं और हमारे कोड में इसके बारे में कुछ कहते हैं:
E : T :: K
आप देख सकते हैं कि मैं इसके साथ कहाँ जा रहा हूँ। मुझे यकीन है कि कोड से प्रकार की जानकारी को अलग करने से इस प्रकार के आत्म-संदर्भितता से बचना संभव होगा, हालांकि इससे प्रकार उनके स्वाद में बहुत "लिस्प" नहीं होंगे। इसके आस-पास संभवतः कई तरीके हैं, हालांकि यह मेरे लिए स्पष्ट नहीं है जो सबसे अच्छा होगा।
संपादित करें: ओह, इसलिए गुग्लिंग के एक बिट के साथ, मैंने क्यूई पाया , जो लिस्प के समान प्रतीत होता है, सिवाय इसके कि यह सांख्यिकीय रूप से टाइप किया गया है। शायद यह देखना शुरू करने के लिए एक अच्छी जगह है जहाँ उन्होंने स्थैतिक टाइपिंग प्राप्त करने के लिए बदलाव किए हैं।