क्या एक सांख्यिकीय-टाइप पूर्ण लिस्प संस्करण संभव है?


107

क्या एक सांख्यिकीय-टाइप पूर्ण लिस्प संस्करण संभव है? यह भी कुछ इस तरह मौजूद है के लिए समझ में आता है? मेरा मानना ​​है कि लिस्प भाषा का एक गुण इसकी परिभाषा की सरलता है। क्या स्थैतिक टाइपिंग इस मूल सिद्धांत से समझौता करेगा?


10
मुझे लिस्प का फ्रीफॉर्म मैक्रोज़ पसंद है, लेकिन मुझे हास्केल के टाइप सिस्टम की मजबूती पसंद है। मुझे यह देखना अच्छा लगेगा कि एक स्टेटिक-टाइप किया हुआ लिस्प कैसा दिखता है।
mcandre

4
अच्छा प्रश्न! मेरा मानना है कि shenlanguage.org ऐसा करता है। काश यह और मुख्यधारा बन जाता।
हामिश ग्रुबीजन


हास्केल के साथ आप प्रतीकात्मक कंप्यूटिंग कैसे करते हैं? ('x' (= (xy) (* xy)) हल करें। यदि आप इसे एक तार में रखते हैं तो कोई जाँच नहीं होती है (लिस्प के विपरीत जो जाँच जोड़ने के लिए मैक्रोज़ का उपयोग कर सकता है)। यदि आप बीजगणितीय डेटा प्रकारों या सूचियों का उपयोग करते हैं ... यह बहुत क्रियात्मक होगा: हल (Sym "x") (Eq (प्लस (Sym "x")) (Sym "y") (बहु (Sym "x")) (सिम "वाई"))
aoeu256

जवाबों:


57

हां, यह बहुत संभव है, हालांकि एक मानक एचएम-शैली प्रकार प्रणाली आमतौर पर सबसे मुहावरेदार लिस्प / योजना कोड के लिए गलत विकल्प है। हाल की भाषा के लिए टाइप किया गया रैकेट देखें जो स्थिर टाइपिंग के साथ "पूर्ण लिस्प" (योजना की तरह, वास्तव में) है।


1
यहाँ समस्या यह है कि सूची का प्रकार क्या है जो टाइप किए गए रैकेट प्रोग्राम के संपूर्ण स्रोत कोड को बनाता है?
जोफोर जूल

18
यह आमतौर पर होगा Sexpr
एली बरज़िल्ले

लेकिन फिर, मैं coerce :: a->beval के संदर्भ में लिख सकता हूं । प्रकार की सुरक्षा कहाँ है?
15

2
@ssice: जब आप किसी अनकैप्ड फ़ंक्शन का उपयोग कर रहे होते हैं, evalतो आपको परिणाम देखने के लिए परिणाम की जांच करने की आवश्यकता होती है, जो टाइप किए गए रैक में नया नहीं है (एक फ़ंक्शन के रूप में समान सौदा जो एक यूनियन प्रकार Stringऔर लेता है Number)। यह देखने का एक निहित तरीका है कि यह किया जा सकता है तथ्य यह है कि आप एचएम-स्टेटिकली टाइप की गई भाषा में गतिशील रूप से टाइप की गई भाषा को लिख और उपयोग कर सकते हैं।
एली बरज़िले

37

यदि आप चाहते थे कि एक पूरी तरह से टाइप की गई भाषा जो लिस्प की तरह दिखे , तो आप एक सार वाक्यविन्यास ट्री को परिभाषित करके आसानी से कर सकते हैं जो आपकी भाषा का प्रतिनिधित्व करता है और फिर उस एएसटी को एस-एक्सप्रेशंस में मैप कर सकता है। हालांकि, मुझे नहीं लगता कि मैं परिणाम को लिस्प कहूंगा।

यदि आप कुछ ऐसा चाहते हैं जो वास्तव में सिंटैक्स के अलावा लिस्प-वाई विशेषताओं है, तो यह एक सांख्यिकीय रूप से टाइप की गई भाषा के साथ करना संभव है। हालांकि, लिस्प की कई विशेषताएं हैं जो बहुत उपयोगी स्थिर टाइपिंग से बाहर निकलना मुश्किल हैं। वर्णन करने के लिए, आइए सूची संरचना पर एक नज़र डालें, जिसे कॉन्स कहा जाता है , जो लिस्प का प्राथमिक बिल्डिंग ब्लॉक बनाती है।

विपक्ष को एक सूची (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 को समायोजित कर सकती है जहाँ स्थैतिक प्रकार की जाँच एक मदद से अधिक बाधा होगी, साथ ही साथ जहाँ स्थिर प्रकार की जाँच लाभप्रद होगी, का उपयोग करती है। यह टाइप्ड रैकेट द्वारा लिया गया दृष्टिकोण है , जैसा कि आप टिप्पणियों से देखेंगे।


16
यह उत्तर एक मूलभूत समस्या से ग्रस्त है: आप मान रहे हैं कि स्थैतिक प्रकार के सिस्टम एचएम-शैली के होने चाहिए । मूल अवधारणा जिसे वहां व्यक्त नहीं किया जा सकता है, और लिस्प कोड की एक महत्वपूर्ण विशेषता है, सबटिप करना है। यदि आप टाइप किए गए रैकेट पर एक नज़र डालेंगे, तो आप देखेंगे कि यह किसी भी तरह की सूची को आसानी से व्यक्त कर सकता है - जैसे कि चीजें (Listof Integer)और (Listof Any)। जाहिर है, आपको बाद में बेकार होने का संदेह होगा क्योंकि आप प्रकार के बारे में कुछ नहीं जानते हैं, लेकिन टीआर में, आप बाद में उपयोग कर सकते हैं (if (integer? x) ...)और सिस्टम को पता चल जाएगा कि x1 शाखा में एक इंटेगर है।
एली बरज़िल्ले

5
ओह, और यह टाइप किए गए रैकेट का एक बुरा लक्षण वर्णन है (जो कि कुछ स्थानों पर आपको मिलने वाले अनसुने प्रकार के सिस्टम से अलग है)। टाइप रैकेट है एक स्थिर टाइप किया टाइप किया कोड के लिए कोई क्रम भूमि के ऊपर के साथ, भाषा। रैकेट अभी भी टीआर में कुछ कोड लिखने की अनुमति देता है और कुछ सामान्य अप्रमाणित भाषा में - और इन मामलों के लिए अनुबंधित (डायनामिक चेक) का उपयोग अनपेक्षित कोड के संभावित दुर्व्यवहार से टाइप किए गए कोड की रक्षा के लिए किया जाता है।
एली बारज़िल्ले

1
@ एली बरज़िले: मैंने झूठ बोला, इसके चार भाग हैं: 4. यह मेरे लिए दिलचस्प है कि कैसे उद्योग-स्वीकृत सी ++ कोडिंग शैली धीरे-धीरे जेनेरिक की ओर घटने से दूर जा रही है। कमजोरी यह है कि भाषा इंटरफ़ेस घोषित करने के लिए मदद प्रदान नहीं करती है एक सामान्य फ़ंक्शन का उपयोग करने जा रहा है, कुछ प्रकार की कक्षाएं निश्चित रूप से मदद कर सकती हैं। साथ ही, C ++ 0x प्रकार की खोज जोड़ सकता है। एचएम नहीं, मुझे लगता है, लेकिन उस दिशा में रेंगना?
ओवेन एस।

1
ओवेन: (1) मुख्य बिंदु यह है कि आपको जिस तरह के कोड लिस्पर्स लिखने हैं, उसे व्यक्त करने के लिए उपप्रकारों की आवश्यकता है - और आपके पास एचएम सिस्टम के साथ ऐसा नहीं हो सकता है, इसलिए आप प्रत्येक उपयोग के लिए कस्टम प्रकारों और निर्माणकर्ताओं के लिए मजबूर हैं, जो पूरी तरह से उपयोग करने के लिए और अधिक अजीब बनाता है। उपप्रकारों के साथ एक प्रणाली का उपयोग करते हुए टाइप किए गए रैकेट में एक जानबूझकर डिजाइन निर्णय का एक कोरोलरी था: कि परिणाम कोड को बदलने या कस्टम प्रकार बनाए बिना इस तरह के कोड को व्यक्त करने में सक्षम होना चाहिए ।
एली बरज़िल्ले

1
(२) हाँ, dynamicप्रकार स्थिर भाषाओं में लोकप्रिय हो रहे हैं, गतिशील प्रकार की भाषाओं के कुछ लाभ प्राप्त करने के लिए एक तरह के वर्कअराउंड के रूप में, इन मूल्यों के सामान्य ट्रेडऑफ़ के साथ एक तरह से लिपटे जा रहे हैं जो प्रकारों की पहचान करता है। लेकिन यहां भी टाइप किए गए रैकेट भाषा के भीतर इसे सुविधाजनक बनाने के लिए बहुत अच्छा काम कर रहे हैं - टाइप चेकर प्रकारों के बारे में अधिक जानने के लिए विधेय की घटनाओं का उपयोग करता है। उदाहरण के लिए, रैकेट पृष्ठ पर टाइप किए गए उदाहरण को देखें और देखें कि string?स्ट्रिंग्स की एक सूची के लिए स्ट्रिंग्स और संख्याओं की "कम" कैसे की जाती है।
एली बरज़िल्ले

10

मेरा जवाब, बिना उच्च आत्मविश्वास के शायद है । यदि आप उदाहरण के लिए, SML जैसी भाषा को देखते हैं, और लिस्प के साथ तुलना करते हैं, तो प्रत्येक का कार्यात्मक कोर लगभग समान है। नतीजतन, ऐसा नहीं लगता है कि आपको लिस्प के मूल में फ़ंक्शन टाइपिंग (फ़ंक्शन एप्लिकेशन और प्राइमर वैल्यूज़) के लिए किसी प्रकार का स्टेटिक टाइप करने में बहुत परेशानी होगी।

आपका प्रश्न पूर्ण रूप से कहता है , और जहां मुझे कुछ समस्या आ रही है वह कोड-ए-डेटा दृष्टिकोण है। प्रकार अभिव्यक्ति की तुलना में अधिक सार स्तर पर मौजूद हैं। लिस्प में यह अंतर नहीं है - संरचना में सब कुछ "सपाट" है। यदि हम कुछ अभिव्यक्ति E: T पर विचार करते हैं (जहाँ T अपने प्रकार का कुछ निरूपण है), और फिर हम इस अभिव्यक्ति को सादा ol 'डेटा मानते हैं, तो यहाँ T का प्रकार क्या है? खैर, यह एक तरह का है! एक प्रकार एक उच्च, आदेश प्रकार है, तो चलो आगे बढ़ते हैं और हमारे कोड में इसके बारे में कुछ कहते हैं:

E : T :: K

आप देख सकते हैं कि मैं इसके साथ कहाँ जा रहा हूँ। मुझे यकीन है कि कोड से प्रकार की जानकारी को अलग करने से इस प्रकार के आत्म-संदर्भितता से बचना संभव होगा, हालांकि इससे प्रकार उनके स्वाद में बहुत "लिस्प" नहीं होंगे। इसके आस-पास संभवतः कई तरीके हैं, हालांकि यह मेरे लिए स्पष्ट नहीं है जो सबसे अच्छा होगा।

संपादित करें: ओह, इसलिए गुग्लिंग के एक बिट के साथ, मैंने क्यूई पाया , जो लिस्प के समान प्रतीत होता है, सिवाय इसके कि यह सांख्यिकीय रूप से टाइप किया गया है। शायद यह देखना शुरू करने के लिए एक अच्छी जगह है जहाँ उन्होंने स्थैतिक टाइपिंग प्राप्त करने के लिए बदलाव किए हैं।


ऐसा लगता है कि क्यूई शेन के बाद अगला पुनरावृत्ति है, उसी व्यक्ति द्वारा विकसित किया गया।
डेगॉन

4

लिंक मर चुका है। लेकिन किसी भी मामले में, डायलन को सांख्यिकीय रूप से टाइप नहीं किया गया है।
ब्योर्न लिंडक्विस्ट

@ BjörnLindqvist: यह लिंक डायलन में धीरे-धीरे टाइपिंग जोड़ने के बारे में थीसिस थी।
रेनर जोसविग

1
@ BjörnLindqvist: मैं एक अवलोकन पेपर से जुड़ा हुआ हूं।
रेनर जोसविग

लेकिन धीरे-धीरे टाइपिंग को स्टैटिक टाइपिंग के रूप में नहीं गिना जाता है। यदि ऐसा होता है, तो पिपी को वैधानिक रूप से टाइप किया जाएगा क्योंकि यह क्रमिक टाइपिंग का भी उपयोग करता है।
ब्योर्न लिंडक्विस्ट

2
@ BjörnLindqvist: यदि हम क्रमिक टाइपिंग के माध्यम से स्थैतिक प्रकार जोड़ते हैं और संकलन के दौरान इनकी जाँच की जाती है, तो यह स्थैतिक टाइपिंग है। यह सिर्फ ऐसा नहीं है कि पूरा कार्यक्रम सांख्यिकीय रूप से टाइप किया गया है, लेकिन भागों / क्षेत्रों। homes.sice.indiana.edu/jsiek/what-is-gradual-typing 'क्रमिक टाइपिंग एक प्रकार की प्रणाली है जिसे मैंने 2006 में वालिद ताहा के साथ विकसित किया था जो एक कार्यक्रम के कुछ हिस्सों को गतिशील रूप से टाइप करने की अनुमति देता है और अन्य भागों को सांख्यिकीय रूप से टाइप किया जाता है।'
रेनर जोसविग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.