संरचनात्मक प्रकार की प्रणाली

From alpha
Jump to navigation Jump to search

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

विवरण

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

उदाहरण के लिए, OCaml ऑब्जेक्ट प्रकारों की अनुकूलता के लिए तरीकों पर संरचनात्मक टाइपिंग का उपयोग करता है। गो (प्रोग्रामिंग भाषा) इंटरफ़ेस के साथ किसी प्रकार की अनुकूलता निर्धारित करने के लिए तरीकों पर संरचनात्मक टाइपिंग का उपयोग करता है। C++#Templates|C++ टेम्प्लेट फ़ंक्शंस प्रकार के तर्कों पर संरचनात्मक टाइपिंग प्रदर्शित करते हैं। मिला हुआ संरचनात्मक टाइपिंग का उपयोग करता है, लेकिन कक्षाएं संरचनात्मक रूप से उपप्रकारित नहीं होती हैं।

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

अनुमानित और गैर-अनुमानित बहुरूपता के लिए संरचनात्मक प्रतिस्थापन के बीच एक अंतर मौजूद है। कुछ भाषाएं, जैसे कि हास्केल (प्रोग्रामिंग भाषा), उस मामले में संरचनात्मक रूप से स्थानापन्न नहीं करती हैं जहां एक अपेक्षित प्रकार घोषित किया जाता है (यानी, अनुमानित नहीं), उदाहरण के लिए, केवल उन कार्यों के लिए स्थानापन्न होता है जो प्रकार अनुमान के माध्यम से हस्ताक्षर-आधारित बहुरूपी होते हैं।[1] फिर गलती से एक गैर-अनुमानित प्रकार को उपप्रकार देना संभव नहीं है, हालांकि एक गैर-अनुमानित प्रकार में एक स्पष्ट रूपांतरण प्रदान करना अभी भी संभव हो सकता है, जिसे अंतर्निहित रूप से लागू किया जाता है।

संरचनात्मक उपप्रकार निश्चित रूप से नाममात्र प्रकार प्रणाली की तुलना में अधिक लचीला है, क्योंकि यह तदर्थ प्रकार और प्रोटोकॉल (वस्तु-उन्मुख प्रोग्रामिंग) के निर्माण की अनुमति देता है; विशेष रूप से, यह एक ऐसे प्रकार के निर्माण की अनुमति देता है जो मौजूदा प्रकार का एक सुपरटाइप है, बाद वाले की परिभाषा को संशोधित किए बिना। हालाँकि, यह वांछनीय नहीं हो सकता है जहाँ प्रोग्रामर बंद अमूर्तताएँ बनाना चाहता है।

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

1990 में, कुक और अन्य ने साबित किया कि संरचनात्मक रूप से टाइप की गई OO भाषाओं में वंशानुक्रम उपप्रकारण नहीं है।[2] संरचनात्मक टाइपिंग के आधार पर यह जांचना कि दो प्रकार संगत हैं, एक गैर-तुच्छ ऑपरेशन है, उदाहरण के लिए, पिछले चेक किए गए प्रकारों के ढेर को बनाए रखने की आवश्यकता होती है।[3]


उदाहरण

OCaml में ऑब्जेक्ट संरचनात्मक रूप से उनके तरीकों के नाम और प्रकार से टाइप किए जाते हैं।

वस्तुओं को नाममात्र वर्ग से गुजरे बिना सीधे (तत्काल वस्तुएं) बनाया जा सकता है। कक्षाएँ केवल वस्तुएँ बनाने के कार्य के रूप में कार्य करती हैं। <सिंटैक्सहाइलाइट लैंग= ओकैमल हाइलाइट= 7 >

# चलो x =
    वस्तु
      वैल म्यूटेबल x = 5
      विधि get_x = x
      विधि set_x y = x <- y
    अंत;;
वैल x : < get_x : int; set_x : int -> इकाई > = <obj>

</सिंटैक्सहाइलाइट> यहां OCaml इंटरैक्टिव रनटाइम सुविधा के लिए ऑब्जेक्ट के अनुमानित प्रकार को प्रिंट करता है। इसका प्रकार (< get_x : int; set_x : int -> unit >) केवल इसकी विधियों द्वारा परिभाषित किया गया है। दूसरे शब्दों में, x का प्रकार किसी नाम के बजाय विधि प्रकार get_x : int और set_x : int -> यूनिट द्वारा परिभाषित किया गया है।[4] किसी अन्य ऑब्जेक्ट को परिभाषित करने के लिए, जिसमें समान विधियाँ और प्रकार की विधियाँ हों: <सिंटैक्सहाइलाइट लैंग= ओकैमल हाइलाइट= 6 >

# चलो y =
    वस्तु
      विधि get_x = 2
      विधि set_x y = Printf.printf %d\n y
    अंत;;
वैल y : < get_x : int; set_x : int -> इकाई > = <obj>

</सिंटैक्सहाइलाइट> OCaml इन्हें एक ही प्रकार का मानता है। उदाहरण के लिए, समानता ऑपरेटर को केवल एक ही प्रकार के दो मान लेने के लिए टाइप किया जाता है: <सिंटैक्सहाइलाइट लैंग= ओकैमल हाइलाइट= 2 >

# एक्स = वाई;;
- : बूल = गलत

</सिंटैक्सहाइलाइट> इसलिए वे एक ही प्रकार के होने चाहिए, अन्यथा यह टाइप-चेक भी नहीं करेगा। इससे पता चलता है कि प्रकारों की तुल्यता संरचनात्मक है।

कोई एक फ़ंक्शन को परिभाषित कर सकता है जो एक विधि को आमंत्रित करता है: <सिंटैक्सहाइलाइट लैंग= ओकैमल हाइलाइट= 2 >

# मान लीजिए set_to_10 a = a#set_x 10;;
वैल set_to_10 : < set_x : int -> 'a; .. > -> 'ए = <मज़ा>

</सिंटैक्सहाइलाइट> पहले तर्क के लिए अनुमानित प्रकार (< set_x : int -> 'a; .. >) दिलचस्प है। .. e> का अर्थ है कि पहला तर्क कोई भी ऑब्जेक्ट हो सकता है जिसमें set_x विधि है, जो तर्क के रूप में एक int लेता है।

इसलिए इसका उपयोग वस्तु पर किया जा सकता है x: <सिंटैक्सहाइलाइट लैंग= ओकैमल हाइलाइट= 2 >

# set_to_10 x;;
- : इकाई = ()

</सिंटैक्सहाइलाइट>

एक अन्य वस्तु बनाई जा सकती है जिसमें वह विधि और विधि प्रकार हो; अन्य विधियाँ अप्रासंगिक हैं: <सिंटैक्सहाइलाइट लैंग= ओकैमल हाइलाइट= 6 >

# चलो z =
    वस्तु
      विधि ब्लाब्लाह = 2.5
      विधि set_x y = Printf.printf %d\n y
    अंत;;
वैल जेड : < ब्लाहब्लाह : फ्लोट; set_x : int -> इकाई > = <obj>

</सिंटैक्सहाइलाइट>

Set_to_10 फ़ंक्शन भी इस पर काम करता है:

सिंटैक्सहाइलाइट लैंग = ओकैमल >

# set_to_10 z;;
10
- : इकाई = ()

</सिंटैक्सहाइलाइट> इससे पता चलता है कि विधि मंगलाचरण जैसी चीज़ों के लिए अनुकूलता संरचना द्वारा निर्धारित की जाती है।

आइए हम वस्तुओं के लिए एक प्रकार का पर्यायवाची परिभाषित करें जिसमें केवल get_x विधि हो और कोई अन्य विधि न हो: <सिंटैक्सहाइलाइट लैंग= ओकैमल हाइलाइट= 2 >

# टाइप करें Simpler_obj = < get_x : int >;;
Simpler_obj = < get_x : int > टाइप करें

</सिंटैक्सहाइलाइट>

जो वस्तु x इस प्रकार का नहीं है; लेकिन संरचनात्मक रूप से, x इस प्रकार का एक उपप्रकार है, चूँकि x इसमें इसके तरीकों का एक सुपरसेट शामिल है। इसलिए x इस प्रकार के लिए बाध्य किया जा सकता है: <सिंटैक्सहाइलाइट लैंग= ओकैमल हाइलाइट= 2,4 >

# (x :> सरल_ओबीजे);;
- : सरल_ओबीजे = <ओबीजे>
# (x :> सरल_ओबीजे)#get_x;;
- : पूर्णांक = 10

</सिंटैक्सहाइलाइट> लेकिन आपत्ति नहीं z, क्योंकि यह एक संरचनात्मक उपप्रकार नहीं है:

# (z :> सरल_ओबीजे);;
इस अभिव्यक्ति को Simpler_obj = < get_x : int > टाइप करने के लिए बाध्य नहीं किया जा सकता;
इसका प्रकार < ब्लाहब्लाह : फ्लोट; set_x : int -> Unit > लेकिन यहां टाइप के साथ प्रयोग किया जाता है
  < get_x : int; .. >
पहले ऑब्जेक्ट प्रकार में कोई विधि get_x नहीं है

इससे पता चलता है कि बढ़ती ज़बरदस्ती के लिए अनुकूलता संरचनात्मक है।

संदर्भ

  1. "हस्ताक्षर-आधारित बहुरूपता".
  2. Cook, W.R.; Hill, W.L.; Canning, P.S. (January 1990). "वंशानुक्रम उपप्रकार नहीं है". Proceedings of the Seventeenth Annual ACM Symposium on Principles of Programming Languages. San Francisco, California: 125–135. doi:10.1145/96709.96721. ISBN 978-0897913430. S2CID 8225906.
  3. "Type compatibility: name vs structural equivalence".
  4. "वस्तु प्रकार".


बाहरी संबंध