रूबी निर्माता ने प्रतीकों की अवधारणा का उपयोग करने के लिए क्यों चुना?


15

tl; dr: क्या प्रतीकों की एक भाषा-अज्ञेय परिभाषा होगी और उन्हें अन्य भाषाओं में रखने का एक कारण होगा?

तो, रूबी निर्माता symbolsने भाषा की अवधारणा का उपयोग क्यों किया ?

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

मुख्य प्रश्न यह है कि क्या symbolsरूबी की अवधारणा प्रदर्शन के लिए मौजूद है, या बस कुछ ऐसा है जिसकी भाषा के लिखे जाने की आवश्यकता है?

क्या रूबी में एक कार्यक्रम हल्का और / या उससे अधिक तेज होगा, आइए हम कहते हैं, पायथन या जावास्क्रिप्ट समकक्ष? यदि हां, तो क्या इसकी वजह होगी symbols?

चूंकि रूबी का एक इरादा इंसानों के लिए पढ़ना और लिखना आसान है, इसलिए क्या इसके रचनाकारों ने इंटरप्रेटर में उन सुधारों को लागू करके कोडिंग की प्रक्रिया को आसान नहीं किया है (जैसा कि अन्य भाषाओं में हो सकता है)?

ऐसा लगता है कि हर कोई केवल यह जानना चाहता है कि क्या symbolsहैं और उनका उपयोग कैसे करना है, और न कि वे पहले स्थान पर क्यों हैं।


स्काला में सिंबल है, मेरे सिर के ऊपर है। मुझे लगता है कि कई लिस्प करते हैं।
डी। बेन नोबल

जवाबों:


17

रूबी, युकीहिरो "मात्ज़" मात्सुमोतो के निर्माता ने इस बारे में एक स्पष्टीकरण पोस्ट किया कि रूबी लिस्प, स्मॉलटॉक, पर्ल (और विकिपीडिया आद्या और एफिल भी बहुत प्रभावित थी):

रूबी निम्नलिखित चरणों में डिज़ाइन की गई भाषा है:

  • एक सरल लिस्प भाषा लें (जैसे सीएल से पहले एक)।
  • मैक्रोज़ हटाएं, एस-एक्सप्रेशन।
  • साधारण ऑब्जेक्ट सिस्टम जोड़ें (CLOS की तुलना में बहुत सरल)।
  • ब्लॉक जोड़ें, उच्च आदेश कार्यों से प्रेरित।
  • स्मालटाक में पाए जाने वाले तरीकों को जोड़ें।
  • पर्ल में पाई जाने वाली कार्यक्षमता जोड़ें (OO तरीके से)।

तो, रूबी मूल रूप से एक लिस्प था, सिद्धांत रूप में।

चलो इसे अब से MatzLisp कहते हैं। ;-)

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

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

इसके अलावा, प्रतीकों को पढ़ने के समय में नजरबंद किया जाता है और उनकी पहचान पहचान से की जा सकती है, जो नए तरह के मूल्यों (जैसे संख्या, लेकिन सार) के लिए एक कुशल तरीका है । यह कोड लिखने में मदद करता है, जहाँ आप प्रतीकात्मक मानों का उपयोग करते हैं, बजाय पूर्णांक द्वारा समर्थित अपने स्वयं के एनम प्रकारों को परिभाषित करने के लिए। इसके अलावा, प्रत्येक प्रतीक अतिरिक्त डेटा धारण कर सकता है। इस प्रकार, उदाहरण के लिए, Emacs / Slime, Emads से मेटाडेटा को एक प्रतीक की संपत्ति सूची में संलग्न कर सकता है।

लिस्प में प्रतीक की धारणा केंद्रीय है। उदाहरण के लिए PAIP (आर्टिफिशियल इंटेलिजेंस प्रोग्रामिंग के प्रतिमान: सामान्य अध्ययन में केस स्टडीज , नॉरविग ) पर एक नज़र डालें ।


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

11

तो, रूबी रचनाकारों को symbolsभाषा में अवधारणा का उपयोग क्यों करना पड़ा ?

खैर, उन्होंने सख्ती से "करने के लिए" नहीं किया, उन्होंने चुना। यह भी ध्यान दें कि कड़ाई से बोलना Symbolभाषा का हिस्सा नहीं है, वे मुख्य पुस्तकालय का हिस्सा हैं। वे करते भाषा स्तरीय शाब्दिक वाक्य रचना है, लेकिन वे बस के रूप में अच्छी तरह से काम लेंगे, जब आप फोन करके उन्हें निर्माण करने के लिए किया था Symbol::new

मैं एक गैर-रूबी प्रोग्रामर के दृष्टिकोण से इसे समझने की कोशिश कर रहा हूं। मैंने बहुत सी अन्य भाषाएं सीखी हैं और उनमें से किसी में भी यह निर्दिष्ट करने की आवश्यकता नहीं है कि मैं रूबी कॉल के साथ काम कर रहा था या नहीं symbols

आपने यह नहीं बताया कि "अन्य भाषाओं के बहुत सारे" क्या हैं, लेकिन यहाँ भाषाओं का एक छोटा सा अंश है जिसमें Symbolरूबीज़ की तरह डेटाटाइप है

अन्य भाषाएं भी हैं जो Symbolअलग रूप में एस की विशेषताएं प्रदान करती हैं । उदाहरण के लिए, जावा में, रूबी की सुविधाओं Stringको दो (वास्तव में तीन) प्रकारों में विभाजित किया गया है: Stringऔर StringBuilder/ StringBuffer। दूसरी ओर, रूबी के Symbolप्रकार की विशेषताओं को जावा Stringप्रकार में बदल दिया जाता है : जावा Stringएस को नजरअंदाज किया जा सकता है , शाब्दिक तार और Stringएस जो संकलन-समय मूल्यांकन किए गए निरंतर अभिव्यक्तियों का परिणाम होते हैं, स्वचालित रूप से नजरबंद कर दिए जाते हैं, गतिशील रूप से उत्पन्न Stringएस को कॉल करके नजरबंद किया जा सकता है। String.internविधि। Stringजावा में इंटर्न बिल्कुल Symbolरूबी में एक जैसा है , लेकिन इसे एक अलग प्रकार के रूप में लागू नहीं किया गया है, यह सिर्फ एक अलग स्थिति है कि एक जावाStringमें हो सकता है (नोट: रूबी के पुराने संस्करणों में, String#to_symकहा जाता था String#internऔर यह विधि आज भी एक विरासत उर्फ ​​के रूप में मौजूद है।)

मुख्य प्रश्न यह हो सकता है: क्या symbolsरूबी की अवधारणा स्वयं और अन्य भाषाओं के प्रदर्शन के इरादे के रूप में मौजूद है,

Symbols पहले और विशिष्ट शब्दार्थ के साथ डेटाटाइप हैं । ये शब्दार्थ कुछ प्रदर्शनकारी कार्यों (जैसे तेज़ ओ (1) समानता परीक्षण) को लागू करना संभव बनाते हैं, लेकिन यह मुख्य उद्देश्य नहीं है।

या सिर्फ कुछ ऐसा है जो भाषा के लिखे जाने के कारण अस्तित्व में है?

Symbols रूबी भाषा में बिलकुल भी आवश्यक नहीं हैं, रूबी उनके बिना ही ठीक काम करेगी। वे विशुद्ध रूप से एक पुस्तकालय सुविधा है। भाषा में ठीक एक स्थान है जो Symbols से बंधा है : एक defविधि परिभाषा अभिव्यक्ति Symbolउस पद्धति के नाम को दर्शाने के लिए मूल्यांकन करती है जिसे परिभाषित किया जा रहा है। हालाँकि, यह एक हालिया बदलाव है, इससे पहले, वापसी मूल्य केवल अनिर्दिष्ट था। एमआरआई ने केवल मूल्यांकन किया nil, रुबिनियस ने किसी Rubinius::CompiledMethodवस्तु का मूल्यांकन किया , और इसी तरह। यह भी मूल्यांकन करना संभव होगा UnboundMethod… या सिर्फ ए String

क्या रूबी में एक कार्यक्रम हल्का और / या उससे अधिक तेज होगा, जो कहता है, पायथन या नोड समकक्ष? यदि हां, तो क्या इसकी वजह होगी symbols?

मुझे यकीन नहीं है कि आप यहां क्या पूछ रहे हैं। प्रदर्शन ज्यादातर कार्यान्वयन गुणवत्ता का विषय है, भाषा का नहीं। इसके अलावा, नोड भी एक भाषा नहीं है, यह ECMAScript के लिए एक व्यवस्थित I / O ढांचा है। IronPython और MRI पर एक समान स्क्रिप्ट चलाने से, IronPython के तेज होने की संभावना है। CPython और JRuby + Truffle पर एक समान स्क्रिप्ट चलाने से JRuby + Truffle के तेज़ी से चलने की संभावना है। यह Symbolएस के साथ कुछ भी नहीं है लेकिन कार्यान्वयन की गुणवत्ता के साथ है: JRuby + Truffle में आक्रामक रूप से अनुकूलन करने वाला कंपाइलर है, साथ ही उच्च प्रदर्शन वाले JVM का संपूर्ण अनुकूलन तंत्र, CPython एक सरल दुभाषिया है।

चूंकि रूबी का एक इरादा इंसानों के लिए पढ़ना और लिखना आसान है, क्या इसके निर्माता दुभाषिया में उन सुधारों को लागू करके कोडिंग की प्रक्रिया को आसान नहीं बना सकते थे (जैसा कि अन्य भाषाओं में हो सकता है)?

सं Symbol। कंपाइलर ऑप्टिमाइज़ेशन नहीं हैं। वे विशिष्ट शब्दार्थ के साथ एक अलग डेटाटाइप हैं। वे YARV की तरह नहीं हैं flonums है, जिसके लिए एक निजी आंतरिक अनुकूलन कर रहे हैं Floatरों। स्थिति समान नहीं है Integer, Bignumऔर Fixnum, जो एक अदृश्य निजी आंतरिक अनुकूलन विवरण होना चाहिए , लेकिन दुर्भाग्य से नहीं है। (यह अंत में रूबी 2.4 में तय होने जा रहा है, जो हटाता है Fixnumऔर Bignumबस छोड़ देता है Integer।)

इसे करने का तरीका जावा करता है, सामान्य Stringएस के एक विशेष राज्य के रूप में इसका मतलब है कि आपको हमेशा इस बात से सावधान रहने की आवश्यकता है कि आपका Stringएस उस विशेष स्थिति में है या नहीं और किन परिस्थितियों में वे स्वचालित रूप से उस विशेष स्थिति में हैं और कब नहीं। यह एक अलग डेटाटाइप होने की तुलना में बहुत अधिक बोझ है।

क्या प्रतीकों की एक भाषा-अज्ञेय परिभाषा होगी और उन्हें अन्य भाषाओं में रखने का एक कारण होगा?

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

किसी भाषा में उनके होने के कारण वास्तव में एक ही हैं, भाषा से स्वतंत्र। कुछ भाषाएं दूसरों की तुलना में उन पर अधिक भरोसा करती हैं।

उदाहरण के लिए, लिस्प परिवार में, "चर" की कोई अवधारणा नहीं है। इसके बजाय, आप Symbolमूल्यों से जुड़े हैं।

चिंतनशील या आत्मविश्लेषी क्षमताओं के साथ भाषाओं में, Symbolरों अक्सर रूबी में, प्रतिबिंब एपीआई में परिलक्षित संस्थाओं के नाम निरूपित करने के लिए जैसे, उपयोग किया जाता है Object#methods, Object#singleton_methods, Object#public_methods, Object#protected_methods, और Object#public_methodsएक वापसी Arrayकी Symbolहै (हालांकि वे बस के रूप में अच्छी तरह से एक वापसी कर सकता है Arrayकी Methodरों)। एक तर्क के रूप में भेजने के लिए संदेश के नाम को दर्शाते हुए Object#public_sendलेता है Symbol(हालाँकि यह एक Stringरूप में अच्छी तरह से स्वीकार करता है , Symbolअधिक अर्थपूर्ण रूप से सही है)।

ECMAScript में, भविष्य में ECMAScript क्षमता को सुरक्षित बनाने का Symbolएक मूलभूत निर्माण खंड है। वे प्रतिबिंब में भी बड़ी भूमिका निभाते हैं।


एरलैंग परमाणुओं को प्रोलॉग से सीधे ले जाया गया (रॉबर्ट वीरिंग ने मुझे बताया कि किसी बिंदु पर)
ज़ाचरी के

2

रूबी में प्रतीक उपयोगी होते हैं, और आप उन सभी को रूबी कोड पर देखेंगे क्योंकि प्रत्येक प्रतीक को हर बार इसका उपयोग करने के बाद पुन: उपयोग किया जाता है। यह स्ट्रिंग्स पर एक प्रदर्शन में सुधार है क्योंकि स्ट्रिंग में उपयोग किए जाने वाले स्ट्रिंग के प्रत्येक उपयोग को मेमोरी में एक नया ऑब्जेक्ट नहीं बनाया जाता है। उदाहरण के लिए, यदि मैं हैश कुंजी के रूप में एक ही स्ट्रिंग का कई बार उपयोग करता हूं:

my_hash = {"a" => 1, "b" => 2, "c" => 3}
100_000.times { |i| puts my_hash["a"] }

स्ट्रिंग "a" को स्मृति में 101,000 बार बनाया जाता है। अगर मैंने इसके बजाय एक प्रतीक का उपयोग किया है:

my_hash = {a: 1, b: 2, c: 3}
100_000.times { |i| puts my_hash[:a] }

:aस्मृति में प्रतीक अभी भी एक वस्तु है। यह प्रतीकों को तार की तुलना में बहुत अधिक कुशल बनाता है।

अद्यतन यहाँ एक बेंचमार्क ( कोडेक अकादमी से लिया गया ) है जो प्रदर्शन अंतर को प्रदर्शित करता है:

require 'benchmark'

string_AZ = Hash[("a".."z").to_a.zip((1..26).to_a)]
symbol_AZ = Hash[(:a..:z).to_a.zip((1..26).to_a)]

string_time = Benchmark.realtime do
  100_000.times { string_AZ["r"] }
end

symbol_time = Benchmark.realtime do
  100_000.times { symbol_AZ[:r] }
end

puts "String time: #{string_time} seconds."
puts "Symbol time: #{symbol_time} seconds."

यहाँ मेरे MBP के लिए मेरे परिणाम हैं:

String time: 0.1254125550040044 seconds.
Symbol time: 0.07360960397636518 seconds.

एक हैश में सिर्फ चाबियाँ पहचानने के लिए तार बनाम प्रतीकों का उपयोग करने में एक स्पष्ट अंतर है।


मुझे यकीन नहीं है कि यह मामला है। मैं एक ही कोड को कई बार निष्पादित करने के लिए रूबी कार्यान्वयन की अपेक्षा करूंगा, प्रत्येक पुनरावृत्ति के लिए बार-बार कोड को पार्स नहीं कर रहा हूं। यहां तक ​​कि अगर प्रत्येक लेक्सिकल घटना "a"वास्तव में एक ताजा स्ट्रिंग है, तो मुझे लगता है कि आपके उदाहरण में बिल्कुल दो होंगे "a"(और एक कार्यान्वयन भी स्मृति साझा कर सकता है जब तक कि उनमें से एक उत्परिवर्तित नहीं होता)। लाखों तार बनाने के लिए, आपको शायद String.new ("a") का उपयोग करने की आवश्यकता होगी। लेकिन मैं रूबी में अच्छी तरह से वाकिफ नहीं हूं, इसलिए शायद मैं गलत हूं।
coredump

1
कोडेकेडमी के पाठों में से एक में, वे मेरे उदाहरण की तरह, स्ट्रिंग बनाम प्रतीकों के लिए एक बेंचमार्क उत्पन्न करते हैं। मैं इसे उत्तर में जोड़ूंगा।
कीथ मैटिक्स

1
बेंचमार्क जोड़ने के लिए धन्यवाद। आपका परीक्षण हैशटेबल (पहचान बनाम स्ट्रिंग तुलना) में तेजी से परीक्षण के कारण, प्रतीकों के बजाय प्रतीकों का उपयोग करके प्राप्त अपेक्षित लाभ को दर्शाता है, लेकिन ऐसा कोई तरीका नहीं है जिससे हम यह अनुमान लगा सकें कि प्रत्येक पुनरावृत्ति पर तार आवंटित हो जाते हैं। मैंने string_AZ[String.new("r")]यह देखने के लिए एक संस्करण जोड़ा कि क्या इससे कोई फर्क पड़ता है। मुझे स्ट्रिंग्स (मूल संस्करण) के लिए 21ms, प्रतीकों के साथ 7ms और हर बार ताजा स्ट्रिंग्स के साथ 50ms मिलते हैं। तो मैं कहूंगा कि स्ट्रिंग्स को शाब्दिक "r"संस्करण के साथ आवंटित नहीं किया गया है ।
coredump

1
आह, इसलिए मैंने कुछ और खुदाई की, और रूबी 2.1 में, तार वास्तव में साझा किए गए हैं। मैंने स्पष्ट रूप से उस अद्यतन को याद किया; यह बात बताने के लिए धन्यवाद। मूल प्रश्न पर वापस जाते हुए, मुझे लगता है कि दोनों बेंचमार्क प्रतीक बनाम तार की उपयोगिता दिखाते हैं।
कीथ मैटिक्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.