2017-04-06 16 views
7

दो Int64s की एक टपल पर + समारोह का उपयोग करते हुए योग देता है:+ फ़ंक्शन टुपल्स पर क्यों काम करता है?

julia> +((1, 2)) 
3 

हालांकि, एक चर का संदर्भ एक टपल निम्न त्रुटि देता है पर + फ़ंक्शन का उपयोग:

julia> a = (1, 2) 
(1,2) 
julia> +(a) 
ERROR: MethodError: no method matching +(::Tuple{Int64, Int64}) 

मैं मुझे समझ में परेशानी हो रही है कि यह ऐसा क्यों व्यवहार करता है, खासकर जब निम्न कोड सत्य लौटाता है।

julia> typeof(a) == typeof((1, 2)) 
+0

यह बहुत अजीब है! मुझे यकीन नहीं है कि ऐसा क्यों होता है, लेकिन मुझे संदेह है कि यह कुछ अजीब 'प्रचार' quirk है। एक टुपल की राशि प्राप्त करने के लिए, हालांकि, आप 'sum' फ़ंक्शन का उपयोग कर सकते हैं। 'योग (ए)' –

+0

मेरा अनुमान है कि यह '1, 2' दोनों को' Int64' के रूप में पहचान नहीं रहा है। सुनिश्चित नहीं है कि 'जुलिआ' टाइप कास्टिंग के लिए अनुमति देता है लेकिन यदि यह आपके टुपल को '(इंट 64, इंट 64)' –

+0

के रूप में कास्टिंग करने का प्रयास करता है! जूलिया का कौन सा संस्करण आप काम कर रहे हैं? –

उत्तर

6

ध्यान दें कि, तुम्हें क्या लगता हो सकता है के विपरीत,

julia> :(+((1, 2))) 
:(1 + 2) 

यह (+)(1, 2) के लिए एक एकल समारोह कॉल बराबर है। कोई tuple नहीं है, हालांकि वाक्यविन्यास एक tuple की तरह लग सकता है। (जैसा कि आपने देखा है, + फ़ंक्शन, टुपल्स पर काम नहीं करता है।) क्या यह व्यवहार वांछनीय है? वैसे यह bug #12755 के रूप में रिपोर्ट किया गया था, लेकिन फिर तय किया गया। लेकिन फिक्स ने bug #12771 का कारण बना दिया जिसके परिणामस्वरूप फिक्स pull #12772 पर वापस लाया गया।

इस गड़बड़ी का समाधान ऑपरेटरों को स्पष्ट रूप से लिखने के बिना कार्यों के रूप में कॉल करने से बचाना है। यही है, +(1, 2) के बजाय हमेशा (+)(1, 2) लिखें। आप सत्यापित कर सकते हैं कि (+)((1, 2)) आपकी इच्छित त्रुटि को फेंक देता है।

(इस समस्या को केवल, एकल ऑपरेटरों के साथ होता है इसलिए क्यों | और * यह के अधीन नहीं हैं।)


आप रुचि रखते हैं, तो इस समस्या के दिल +(x, y) समारोह के बीच एक बुनियादी अस्पष्टता है कॉल वाक्यविन्यास और यूनरी ऑपरेटर वाक्यविन्यास। यहाँ कुछ स्थितियों कि एकल ऑपरेटर के रूप में + और - पार्स करने के लिए प्रेरित, तब भी जब ( द्वारा पीछा कर रहे हैं:

  • -(x+y)^2 में, यह, ((-)(x+y))^2 अत्यधिक संभावना है कि (-)((x+y)^2) चाहिए था नहीं। इसलिए हम फ़ंक्शन कॉल के रूप में बिना शर्त शर्त -( पार्स कर सकते हैं।
  • इसके बजाय क्या किया जाना चाहिए - एक निश्चित पूर्वता अप करने के लिए पार्स के बाद बात तो यह है कि -x * y(-x) * y, -x + y(-x) + y के रूप में है, लेकिन -x^y-(x^y) के रूप में के रूप में पार्स किया जाता है।
  • अपवाद: लेकिन यह -(1, 2) पार्स को (-)((1, 2)) के रूप में बना देगा, यानी एक टुपल पर एक फ़ंक्शन कहा जाता है। किसी भी कारण या किसी अन्य कारण के लिए, - के बाद की चीज़ फ़ंक्शन कॉल टुपल की तरह दिखने के लिए अपवाद जोड़ने का निर्णय लिया गया था। ऐसा इसलिए है कि +(1, 2) काम करेगा, लेकिन यह वास्तव में ज्यादातर एक हैक है।
  • लेकिन पार्सर के परिप्रेक्ष्य से, ((1, 2)) बिल्कुल (1, 2) जैसा दिखता है; बस पूर्व कोष्ठक में लपेटा गया है।

मेरी व्यक्तिगत राय यह है कि -(1, 2) नोटेशन मूर्खतापूर्ण है (और सभी मामलों में वैसे भी काम नहीं करता है, उदाहरण के लिए -(1, 2)^2 में)।यदि वह अपवाद चारों ओर नहीं था, और -(1, 2) लगातार ट्यूपल पर एक यूनरी फ़ंक्शन कॉल के रूप में पार्स किया गया था, तो अधिक स्थिरता बिना (मुझे लगता है) बहुत नुकसान हो सकता था। एक बाइनरी फ़ंक्शन कॉल वांछित होने पर 1 - 2 या (-)(1, 2) लिखना बहुत बुरा नहीं है।

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