2011-01-25 21 views
11

मुझे पता है कि स्कैला एएलजीओएल से कॉल-बाय-नाम का समर्थन करता है, और मुझे लगता है कि मैं समझता हूं कि इसका अर्थ क्या है, लेकिन क्या स्कैला कॉल-बाय-रेफरेंस जैसे सी #, वीबी.नेट और सी ++ कर सकता है? मुझे पता है कि जावा कॉल-बाय-रेफरेंस नहीं कर सकता है, लेकिन मुझे यकीन नहीं है कि यह सीमा पूरी तरह से भाषा या जेवीएम के कारण है। जब आप एक विधि के लिए एक बहुत बड़ा डेटा संरचना पास करना चाहते हैंसंदर्भ द्वारा स्कैला कॉल कर सकते हैं?

यह उपयोगी होगा, लेकिन आप इसे की एक प्रतिलिपि बनाने के लिए नहीं करना चाहती। इस मामले में कॉल-बाय-रेफरेंस सही लगता है।

+1

मुझे नहीं लगता था कि आप स्कैला में मूल्य के आधार पर डेटा संरचनाएं पारित कर सकते हैं। – Gabe

+0

@Gabe यह अभी भी [पास/कॉल-बाय-वैल्यू] (http://en.wikipedia.org/wiki/Evaluation_strategy) (AnyRef प्रकारों के लिए पास-दर-मूल्य-अंतर्निहित-ऑब्जेक्ट-संदर्भ- पायथन/जावा लोग इसके लिए "पास-बाय-रेफरेंस" शब्द का दुरुपयोग करना चाहते हैं ;-)। हालांकि, पास/कॉल-बाय-रेफरेंस का मतलब है कि फंक्शन * में वैरिएबल * को सेट करने वाले वैरिएबल का मान निर्धारित करेगा (उदाहरण के लिए सी ++ में 'रेफरी' या वीबी में 'बाय्रफ' या सी # में 'आउट/रेफरी') । यह * ऑब्जेक्ट * हो सकता है * पास ऑब्जेक्ट्स और स्टेट म्यूटेशन के साथ, लेकिन यह वही नहीं है (सी पॉइंटर द्वारा संदर्भित मान को संशोधित करके इसे अनुकरण कर सकता है)। –

+1

@pst: मैं "एक विधि के लिए एक विशाल डेटा संरचना पास" भाग का जिक्र कर रहा था। या तो स्कैला का एक तरीका है कि मुझे किसी फ़ंक्शन में पास होने पर डेटा संरचनाओं की प्रतिलिपि बनाने के बारे में पता नहीं था, या डेटा संरचनाएं पहले ही संदर्भ द्वारा पारित की गई हैं और ओपी से उद्धरण अप्रासंगिक है। – Gabe

उत्तर

34

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

चूंकि आप हमेशा ऑब्जेक्ट्स ऑब्जेक्ट्स ऑब्जेक्ट्स पर ऑब्जेक्ट्स पास कर रहे हैं, तो आपको बार-बार एक विशाल ऑब्जेक्ट की प्रतिलिपि बनाने की समस्या नहीं है।

संयोग से, स्काला की कॉल नाम से मूल्य एक समारोह उद्देश्य यह है कि अभिव्यक्ति की परिणाम देता है (एक सूचक) होने के साथ मूल्य द्वारा कॉल का उपयोग कर कार्यान्वित किया जाता है,।

+0

क्या आप परिवर्तनशील क्षेत्रों के प्रभाव के बारे में अपने बिंदु पर विस्तार कर सकते हैं? – royco

+1

अच्छा, मान लें कि आप एक चर 'x' को म्यूट करना चाहते हैं। आप इसे सी में 'int * x' के रूप में पास कर सकते हैं। स्कैला में, आपके पास एक क्लास होल्ड होगा जो वैरिएबल: 'क्लास एक्स (var x: Int) '। अब यदि आप उस वर्ग को किसी विधि से पास करते हैं, तो यह 'x' के मान को बदल सकता है। –

+11

यह कहकर कि स्कैला मूल्य द्वारा कॉल का उपयोग करता है विशेष रूप से भाषा को इसके क्रियान्वयन के साथ भ्रमित कर रहा है। अगर हम असेंबलर जाते हैं, तो सभी भाषाएं विशेष रूप से मूल्य से कॉल करती हैं। स्कैला _could_ जेवीएम पर कॉल-बाय-रेफरेंस का समर्थन करता है, जैसे संदर्भ या आदिम को पारित करने के लिए एक कंटेनर ऑब्जेक्ट बनाने के रूप में, और फिर कॉल रिटर्न के बाद उस कंटेनर से वापस पढ़ना। –

0

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

जावा और स्कैला में, कुछ अंतर्निर्मित (ए/के/एक आदिम) प्रकार स्वचालित रूप से पास-दर-मूल्य (जैसे int या int) प्राप्त करते हैं, और प्रत्येक उपयोगकर्ता परिभाषित प्रकार पास-बाय-रेफरेंस (यानी मैन्युअल रूप से प्रतिलिपि बनाना चाहिए) उन्हें केवल उनके मूल्य को पारित करने के लिए)।

नोट मैं अद्यतन विकिपीडिया के Call-by-sharing section इस और अधिक स्पष्ट बनाने के लिए।

शायद विकिपीडिया पास-दर-मूल्य और कॉल-बाय-वैल्यू के बीच भेद के बारे में उलझन में है? मैंने सोचा कि पास-बाय-वैल्यू अधिक सामान्य शब्द है, क्योंकि यह असाइनमेंट एक्सप्रेशन, साथ ही फ़ंक्शन एप्लिकेशन पर भी लागू होता है। मैं विकिपीडिया में उस सुधार को करने की कोशिश करने के लिए परेशान नहीं था, इसे दूसरों के लिए हैश आउट करने के लिए छोड़ दें।

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


जो लोग इसे नीचे वोट देते हैं वे स्पष्ट रूप से समझ नहीं पाते कि "कॉल-बाय-शेयरिंग" क्या है।

नीचे मैं लिखने अप मैं अपने Copute भाषा के लिए किया था (जो JVM को लक्षित करता है), जहां मैं मूल्यांकन रणनीति पर चर्चा जोड़ देगा।


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

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

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

भाषाओं में आम तौर पर एक डिफ़ॉल्ट मूल्यांकन रणनीति होती है, और कुछ को वैकल्पिक रूप से गैर-डिफ़ॉल्ट में मूल्यांकन करने के लिए फ़ंक्शन को मजबूर करने के लिए एक वाक्यविन्यास होता है। भाषाएं जो डिफ़ॉल्ट रूप से उत्सुक होती हैं, आम तौर पर बुलियन संयोजन (ए/के/ए "और", & &) का मूल्यांकन करती हैं और संयोजन (ए/के/ए "या", ||) ऑपरेटर आलसी, क्योंकि दूसरा ऑपरेंड नहीं है आधे मामलों में जरूरी है, यानी सच || कुछ भी == सत्य और झूठा & & कुछ भी == झूठी।

+0

यहां एक संदर्भ है: http://lambda-the-ultimate.org/node/4180#comment-64168 –

0

स्कैला में संदर्भ पैरामीटर का अनुकरण करने का तरीका यहां दिया गया है।

def someFunc(var_par_x : Function[Int,Unit]) { 
    var_par_x(42) // set the reference parameter to 42 
} 

var y = 0 
someFunc((x => y=x)) 
println(y) 

ठीक है, ठीक है, ठीक नहीं है कि पास्कल या सी ++ प्रोग्रामर का क्या उपयोग किया जाता है; लेकिन फिर, स्कैला में बहुत कम है। उलझन यह है कि यह कॉलर को पैरामीटर को भेजे गए मान के साथ क्या कर सकता है इसके साथ अधिक लचीलापन देता है। जैसे

someFunc((x => println(x))) 
संबंधित मुद्दे

 संबंधित मुद्दे