आपके पास इस मुद्दे पर एक अच्छा दृष्टिकोण है:
मार्टिन ओडस्की, भाग III के साथ स्काला के टाइप सिस्टम ए कन्वर्सेशन का उद्देश्य
विथ बिल वेनर्स एंड फ्रैंक सोमरस (18 मई, 2009)
अपडेट (अक्टूबर २०० ९): बिल वीनर्स के इस नए लेख में वास्तव में नीचे दिए गए उदाहरणों का वर्णन किया गया है: स्केल
प्रकार के सदस्य बनाम जेनेरिक टाइप पैरामीटर बनाम स्काला (अंत में सारांश देखें)
(यहां पहला साक्षात्कार, मई 2009 का प्रासंगिक उद्धरण है, मेरा जोर)
सामान्य सिद्धांत
हमेशा अमूर्तता की दो धारणाएँ रही हैं:
- पैरामीटरकरण और
- अमूर्त सदस्य।
जावा में आपके पास भी दोनों हैं, लेकिन यह इस बात पर निर्भर करता है कि आप किस चीज पर अमूर्त हैं।
जावा में आपके पास सार विधियां हैं, लेकिन आप एक विधि को पैरामीटर के रूप में पारित नहीं कर सकते हैं।
आपके पास सार क्षेत्र नहीं हैं, लेकिन आप एक मान को पैरामीटर के रूप में पारित कर सकते हैं।
और इसी तरह आपके पास अमूर्त प्रकार के सदस्य नहीं हैं, लेकिन आप एक पैरामीटर के रूप में एक प्रकार निर्दिष्ट कर सकते हैं।
तो जावा में आपके पास भी ये तीनों हैं, लेकिन इस बात का भेद है कि आप किस अमूर्त सिद्धांत का इस्तेमाल कर सकते हैं। और आप तर्क दे सकते हैं कि यह भेद काफी मनमाना है।
स्केल रास्ता
हमने तीनों प्रकार के सदस्यों के लिए समान निर्माण सिद्धांत तय किए ।
तो आपके पास अमूर्त क्षेत्र और साथ ही मूल्य पैरामीटर हो सकते हैं।
आप मानकों (या "कार्यों") को मापदंडों के रूप में पारित कर सकते हैं, या आप उन पर सार कर सकते हैं।
आप पैरामीटर के रूप में प्रकार निर्दिष्ट कर सकते हैं, या आप उन पर सार कर सकते हैं।
और जो हमें वैचारिक रूप से मिलता है वह यह है कि हम एक दूसरे के संदर्भ में मॉडल बना सकते हैं। कम से कम सिद्धांत रूप में, हम ऑब्जेक्ट-ओरिएंटेड एब्सट्रैक्शन के रूप में हर प्रकार के मापदंडों को व्यक्त कर सकते हैं। तो एक तरह से आप कह सकते हैं कि स्काला एक अधिक रूढ़िवादी और पूर्ण भाषा है।
क्यों?
क्या, विशेष रूप से, अमूर्त प्रकार आप खरीदते हैं इन covariance समस्याओं के लिए एक अच्छा इलाज है जो हमने पहले बात की थी।
एक मानक समस्या, जो लंबे समय से है, जानवरों और खाद्य पदार्थों की समस्या है।
पहेली में Animal
एक विधि के साथ एक वर्ग था eat
, जो कुछ भोजन खाता है।
समस्या यह है कि यदि हम पशु को उपवर्ग में रखते हैं और गाय जैसे वर्ग रखते हैं, तो वे केवल ग्रास ही खाएंगे और मनमाना भोजन नहीं करेंगे। उदाहरण के लिए, एक गाय मछली नहीं खा सकती थी।
आप जो चाहते हैं वह यह कहने में सक्षम है कि एक गाय के पास एक खाने की विधि है जो केवल घास खाती है न कि अन्य चीजें।
वास्तव में, आप जावा में ऐसा नहीं कर सकते क्योंकि यह पता चला है कि आप बिना किसी अनचाहे स्थितियों का निर्माण कर सकते हैं, जैसे कि एक फलन को एक Apple वैरिएबल को असाइन करने की समस्या के बारे में जो मैंने पहले बात की थी।
इसका उत्तर यह है कि आप पशु वर्ग में एक अमूर्त प्रकार जोड़ते हैं ।
आप कहते हैं, मेरे नए पशु वर्ग का एक प्रकार है SuitableFood
, जिसे मैं नहीं जानता।
तो यह एक अमूर्त प्रकार है। आप प्रकार का कार्यान्वयन नहीं करते हैं। तब आपके पास एक ऐसी eat
विधि है जो केवल खाती है SuitableFood
।
और फिर Cow
कक्षा में मैं कहूंगा, ठीक है, मेरे पास एक गाय है, जो कक्षा का विस्तार करती है Animal
, और इसके लिए Cow type SuitableFood equals Grass
।
इसलिए अमूर्त प्रकार एक सुपरक्लास में एक प्रकार की यह धारणा प्रदान करते हैं जो मुझे नहीं पता है, जिसे मैं बाद में उप-वर्ग में कुछ ऐसी चीजों के साथ भर देता हूं जो मुझे पता है ।
मानकीकरण के साथ भी?
वास्तव में आप कर सकते हैं। आप भोजन के प्रकार के साथ वर्ग पशु को पैरामीटर कर सकते हैं।
लेकिन व्यवहार में, जब आप ऐसा करते हैं, तो कई अलग-अलग चीजों के साथ, यह मापदंडों के विस्फोट की ओर जाता है , और आमतौर पर, मापदंडों की सीमा में और क्या है ।
1998 ECOOP में, किम ब्रूस, फिल वाडलर, और मेरे पास एक पेपर था जहां हमने दिखाया कि जैसे-जैसे आप उन चीजों की संख्या बढ़ाते हैं, जिन्हें आप नहीं जानते हैं, विशिष्ट कार्यक्रम चतुष्कोणीय रूप से बढ़ेगा ।
इसलिए मापदंडों को नहीं करने के लिए बहुत अच्छे कारण हैं, लेकिन इन सार सदस्यों के पास होने के लिए, क्योंकि वे आपको यह द्विघात झटका नहीं देते हैं।
टिप्पणी में पुछता है:
क्या आपको लगता है कि निम्नलिखित एक उचित सारांश है:
- अमूर्त प्रकार का उपयोग 'has-a' या 'use-a' रिश्तों में किया जाता है (जैसे a
Cow eats Grass
)
- जहाँ सामान्य रूप से 'रिश्ते' (जैसे
List of Ints
) होते हैं
मुझे यकीन नहीं है कि यह संबंध अमूर्त प्रकार या जेनरिक का उपयोग करने के बीच भिन्न है। क्या अलग है:
- उनका उपयोग कैसे किया जाता है, और
- कैसे पैरामीटर सीमा का प्रबंधन कर रहे हैं।
यह समझने के लिए कि मार्टिन क्या बोल रहा है जब "मापदंडों के विस्फोट की बात आती है, और आमतौर पर, मापदंडों की सीमा में अधिक क्या होता है ", और इसके बाद के चतुष्कोणीय विकास जब अमूर्त प्रकार जेनेरिक का उपयोग करके मॉडलिंग की जाती है, तो आप कागज पर विचार कर सकते हैं " स्केलर कंपोनेंट एब्स्ट्रेक्शन। "द्वारा लिखित ... मार्टिन ओडस्की, और ओओपीएसएलए 2005 के लिए मथायस ज़ेंगर, प्रोजेक्ट पालकॉम के प्रकाशनों में संदर्भित (2007 में समाप्त)।
प्रासंगिक अर्क
परिभाषा
अमूर्त प्रकार के सदस्य ठोस प्रकार के घटकों पर अमूर्त करने का एक लचीला तरीका प्रदान करते हैं। एसएमएल हस्ताक्षर
में उनके उपयोग के समान, घटक प्रकार के घटकों के बारे में जानकारी छिपा सकते हैं । ऑब्जेक्ट-ओरिएंटेड फ्रेमवर्क में, जहाँ कक्षाएं वंशानुक्रम द्वारा विस्तारित की जा सकती हैं, उन्हें मानकीकरण के लचीले साधन के रूप में भी इस्तेमाल किया जा सकता है (अक्सर इसे परिवार बहुरूपता कहा जाता है, उदाहरण के लिए इस वेबलॉग प्रविष्टि को देखें , और एरिक अर्न्स्ट द्वारा लिखित पेपर )।
(नोट: पारिवारिक बहुरूपता को वस्तु-उन्मुख भाषाओं के लिए पुन: प्रयोज्य अभी तक प्रकार-सुरक्षित पारस्परिक पुनरावर्ती वर्गों के समर्थन के लिए प्रस्तावित किया गया है।
एक महत्वपूर्ण विचार परिवारों की धारणा है, जो पारस्परिक रूप से पुनरावर्ती वर्गों के लिए उपयोग किए जाते हैं)
बाध्य प्रकार अमूर्त
abstract class MaxCell extends AbsCell {
type T <: Ordered { type O = T }
def setMax(x: T) = if (get < x) set(x)
}
यहां, टी के प्रकार की घोषणा एक ऊपरी प्रकार की बाध्यता से बाध्य है जिसमें एक वर्ग का नाम क्रमबद्ध और एक शोधन शामिल है { type O = T }
।
ऊपरी बाध्य टी उपविशेषों में उप के आदेशों को उन आदेशों के उपप्रकारों तक सीमित कर देता है, जिनके लिए सदस्य O
के प्रकार equals T
।
इस अड़चन के कारण, <
ऑर्डर किए गए क्लास के तरीके को एक रिसीवर पर लागू होने की गारंटी दी जाती है और टाइप T का एक तर्क दिया जाता है
। उदाहरण से पता चलता है कि बंधे हुए टाइप मेंबर खुद बाउंड के हिस्से के रूप में दिखाई दे सकते हैं।
(यानी स्काला एफ-बाउंड पॉलिमॉर्फिज्म का समर्थन करता है )
(नोट, पीटर कैनिंग, विलियम कुक, वाल्टर हिल, वाल्टर ओलथॉफ पेपर से: बाउंडेड
मात्रा का ठहराव कार्डेली और वेगनर द्वारा टाइपिंग कार्यों के रूप में पेश किया गया था जो किसी दिए गए प्रकार के सभी उपप्रकारों पर समान रूप से काम करते हैं।
उन्होंने एक सरल "ऑब्जेक्ट" मॉडल को परिभाषित किया है । और टाइप-चेक फ़ंक्शंस के लिए बाध्य परिमाणीकरण का उपयोग किया गया है, जो "विशेषता" के एक निर्दिष्ट सेट वाले सभी ऑब्जेक्ट्स पर समझ में आता है।
ऑब्जेक्ट-ओरिएंटेड भाषाओं की अधिक यथार्थवादी प्रस्तुति उन ऑब्जेक्ट्स की अनुमति देगा जो पुनरावर्ती-परिभाषित प्रकारों के तत्व हैं ।
इस संदर्भ में, बाउंडेड। परिमाणीकरण अब अपने इच्छित उद्देश्य को पूरा नहीं करता है। ऐसे कार्यों को खोजना आसान है जो सभी वस्तुओं पर एक निर्दिष्ट पद्धति के साथ समझ में आता है, लेकिन जिसे कार्डेली-वेगनर प्रणाली में टाइप नहीं किया जा सकता है।
ऑब्जेक्ट-ओरिएंटेड भाषाओं में टाइप किए गए बहुरूप कार्यों के लिए एक आधार प्रदान करने के लिए, हम एफ-बाउंड मात्रा का परिचय देते हैं)
एक ही सिक्के के दो चेहरे
प्रोग्रामिंग भाषाओं में अमूर्तता के दो प्रमुख रूप हैं:
- पैरामीटरकरण और
- अमूर्त सदस्य।
पहला रूप कार्यात्मक भाषाओं के लिए विशिष्ट है, जबकि दूसरा रूप आमतौर पर ऑब्जेक्ट-ओरिएंटेड भाषाओं में उपयोग किया जाता है।
परंपरागत रूप से, जावा मानों के लिए मानकीकरण का समर्थन करता है, और संचालन के लिए सदस्य अमूर्तता। जेनेरिक के साथ हाल ही में जावा 5.0 प्रकार के लिए भी मानकीकरण का समर्थन करता है।
स्काला में जेनरिक को शामिल करने के तर्क दो-गुना हैं:
सबसे पहले, अमूर्त प्रकार में एन्कोडिंग हाथ से करने के लिए सीधा नहीं है। सुगमता में कमी के अलावा, अमूर्त प्रकार के नामों के बीच आकस्मिक नाम संघर्षों की समस्या भी है जो प्रकार के मापदंडों का अनुकरण करते हैं।
दूसरा, जेनरिक और अमूर्त प्रकार आमतौर पर स्काला कार्यक्रमों में अलग भूमिका निभाते हैं।
- आम तौर पर जेनरिक का उपयोग तब किया जाता है जब किसी को सिर्फ इंस्टेंटेशन टाइप करना होता है , जबकि
- अमूर्त प्रकार आमतौर पर तब उपयोग किए जाते हैं जब ग्राहक कोड से सार प्रकार को संदर्भित करने की आवश्यकता होती है ।
उत्तरार्द्ध विशेष रूप से दो स्थितियों में उत्पन्न होता है:
- एक ग्राहक कोड से एक प्रकार के सदस्य की सटीक परिभाषा को छिपाने के लिए, SML- शैली मॉड्यूल सिस्टम से ज्ञात इनकैप्सुलेशन प्राप्त करना चाहता हो सकता है।
- या कोई व्यक्ति परिवार के बहुरूपता को प्राप्त करने के लिए उपवर्गों में covariantly प्रकार को ओवरराइड करना चाह सकता है।
बंधी हुई बहुरूपता वाली प्रणाली में, जेनेटिक्स में अमूर्त प्रकार को फिर से लिखना एक प्रकार का सीमा विस्तार हो सकता है ।
अद्यतन अक्टूबर 2009
स्केल प्रकार के सदस्य बनाम स्काला में सामान्य प्रकार के पैरामीटर (बिल वेनर)
(जोर मेरा)
सार प्रकार के सदस्यों के बारे में अब तक का मेरा अवलोकन है कि वे मुख्य रूप से सामान्य प्रकार के मापदंडों से बेहतर विकल्प हैं जब:
- आप लोगों को लक्षणों के माध्यम से उन प्रकारों की परिभाषाओं में मिश्रण करने देना चाहते हैं ।
- आपको लगता है कि जब यह परिभाषित किया जा रहा है तो सदस्य के नाम का स्पष्ट उल्लेख कोड पठनीयता में मदद करेगा ।
उदाहरण:
यदि आप तीन अलग-अलग फ़िक्चर ऑब्जेक्ट को परीक्षणों में पास करना चाहते हैं, तो आप ऐसा कर पाएंगे, लेकिन आपको तीन प्रकार निर्दिष्ट करने होंगे, प्रत्येक पैरामीटर के लिए एक। इस प्रकार मैंने टाइप पैरामीटर दृष्टिकोण अपना लिया था, आपकी सुइट कक्षाएं इस तरह से समाप्त हो सकती थीं:
// Type parameter version
class MySuite extends FixtureSuite3[StringBuilder, ListBuffer, Stack] with MyHandyFixture {
// ...
}
जबकि प्रकार सदस्य दृष्टिकोण के साथ यह इस प्रकार होगा:
// Type member version
class MySuite extends FixtureSuite3 with MyHandyFixture {
// ...
}
अमूर्त प्रकार के सदस्यों और सामान्य प्रकार के मापदंडों के बीच एक अन्य मामूली अंतर यह है कि जब एक सामान्य प्रकार का पैरामीटर निर्दिष्ट किया जाता है, तो कोड के पाठकों को टाइप पैरामीटर का नाम नहीं दिखता है। इस प्रकार कोड की इस लाइन को देखने के लिए कोई था:
// Type parameter version
class MySuite extends FixtureSuite[StringBuilder] with StringBuilderFixture {
// ...
}
उन्हें पता नहीं होगा कि स्ट्रिंगबर्ल के रूप में निर्दिष्ट प्रकार के पैरामीटर का नाम क्या था, इसे देखे बिना। जबकि सार प्रकार सदस्य दृष्टिकोण में कोड में टाइप पैरामीटर का नाम वहीं है:
// Type member version
class MySuite extends FixtureSuite with StringBuilderFixture {
type FixtureParam = StringBuilder
// ...
}
बाद के मामले में, कोड के पाठक देख सकते हैं कि StringBuilder
"स्थिरता पैरामीटर" प्रकार है।
उन्हें अभी भी यह पता लगाने की आवश्यकता होगी कि "स्थिरता पैरामीटर" का क्या मतलब है, लेकिन वे कम से कम दस्तावेज में देखे बिना प्रकार का नाम प्राप्त कर सकते हैं।