2008-09-19 25 views
95

मैं सवाल पर इस उद्धरण देखा: What is a good functional language on which to build a web service?क्या JVM पूंछ कॉल अनुकूलन को रोकता है?

विशेष आत्म पुनरावर्ती कार्यों को छोड़कर पूंछ-कॉल उन्मूलन का समर्थन नहीं करता में स्काला, जो रचना आप कर सकते हैं के प्रकार को सीमित करता है (यह एक मौलिक सीमा है जेवीएम का)।

क्या यह सच है? यदि हां, तो यह जेवीएम के बारे में क्या है जो इस मौलिक सीमा को बनाता है?

उत्तर

72

यह पोस्ट: Recursion or Iteration? मदद कर सकता है।

संक्षेप में, सुरक्षा मॉडल की वजह से जेवीएम में पूंछ कॉल अनुकूलन करना मुश्किल है और हमेशा एक स्टैक ट्रेस उपलब्ध होने की आवश्यकता है। इन आवश्यकताओं को सिद्धांत में समर्थित किया जा सकता है, लेकिन शायद इसे एक नया बाइटकोड की आवश्यकता होगी (John Rose's informal proposal देखें)।

वहाँ भी Sun bug #4726340 में अधिक चर्चा है, जहां मूल्यांकन (2002 से) समाप्त होता है:

मेरा मानना ​​है कि यह फिर भी किया जा सकता है, लेकिन यह एक छोटे से कार्य नहीं है।

वर्तमान में, Da Vinci Machine प्रोजेक्ट में कुछ काम चल रहा है। पूंछ कॉल सबप्रोजेक्ट की स्थिति "प्रोटो 80%" के रूप में सूचीबद्ध है; जावा 7 में इसे बनाने की संभावना नहीं है, लेकिन मुझे लगता है कि इसका जावा 8 पर बहुत अच्छा मौका है।

+0

मैंने स्पष्टीकरण का काफी पालन नहीं किया। मैंने सोचा कि कंपाइलर द्वारा पूंछ-कॉल अनुकूलन लागू किया गया था। मान लें कि आपके पास एक ऐसा फ़ंक्शन है जो कंपाइलर द्वारा अनुकूलित पूंछ-कॉल हो सकता है, फिर भी आपके पास समकक्ष गैर-रिकर्सिव फ़ंक्शन हो सकता है जो लूप का उपयोग करके समान कार्यक्षमता लागू करता है, सही? यदि ऐसा है, तो यह संकलक द्वारा नहीं किया जा सका। मैं JVM पर निर्भरता का पालन करने में सक्षम नहीं हूं। यह देशी आई386 कोड उत्पन्न करने वाले स्कीम कंपाइलर के साथ तुलना कैसे करता है? –

+0

ठीक है, बस नीचे जॉन का जवाब देखा। इसलिए, ऐसा नहीं है कि इसे कार्यान्वित नहीं किया जा सकता है, यह उचित डीबगर समर्थन –

+4

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

8

लैम्ब्डा द अल्टीमेट (ऊपर पोस्ट किए गए लिंक मिमीर्स से) पेपर के अलावा, जॉन रोज़ सूर्य से पूंछ कॉल अनुकूलन के बारे में कुछ और कहना है।

http://blogs.oracle.com/jrose/entry/tail_calls_in_the_vm

मैंने सुना है कि यह किसी दिन JVM पर लागू किया जा सकता है। अन्य चीजों के साथ टेल कॉल समर्थन दा विंची मशीन पर देखा जा रहा है।

http://openjdk.java.net/projects/mlvm/

27

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

तो जेवीएम किसी भी उत्पादन-गुणवत्ता वाली कार्यात्मक प्रोग्रामिंग भाषाओं का समर्थन नहीं कर सकता है जब तक कि सूर्य लागू करने वाली पूंछ JVM में ही कॉल न हो जाए। वे वर्षों से इस पर चर्चा कर रहे हैं लेकिन मुझे संदेह है कि वे कभी भी पूंछ कॉल लागू करेंगे: यह बहुत मुश्किल होगा क्योंकि उन्होंने ऐसी बुनियादी कार्यक्षमता को लागू करने से पहले अपने वीएम को समय-समय पर अनुकूलित किया है, और सूर्य का प्रयास कार्यात्मक भाषाओं की बजाय गतिशील भाषाओं पर दृढ़ता से केंद्रित है।

इसलिए एक बहुत ही मजबूत तर्क है कि स्कैला वास्तविक कार्यात्मक प्रोग्रामिंग भाषा नहीं है: इन भाषाओं ने पूंछ को एक आवश्यक विशेषता के रूप में माना है क्योंकि योजना 30 साल पहले पहली बार पेश की गई थी।

+3

'इसलिए एक बहुत ही मजबूत तर्क है कि स्कैला वास्तविक कार्यात्मक प्रोग्रामिंग भाषा नहीं है' - तर्क वास्तव में काफी कमजोर है। निश्चित रूप से 'पूंछ कॉल [एक] आवश्यक विशेषता' है, और अच्छा है अगर अंतर्निहित हार्डवेयर (या वायरल मशीन) सीधे इसका समर्थन करता है। लेकिन यह कार्यान्वयन विवरण है। – Ingo

+8

@Ingo: केवल तभी जब आप उपयोगकर्ता द्वारा एक महत्वपूर्ण समस्या होने के लिए देखे गए रन-टाइम पर अपने प्रोग्राम में स्टैक ओवरफ़्लो पर विचार नहीं करते हैं। अपने बग ट्रैकर के मुताबिक, स्कैला कंपाइलर भी ढेर ओवरफ्लो से पीड़ित है। तो यहां तक ​​कि सबसे अनुभवी स्कैला डेवलपर्स अभी भी गलत हो रहे हैं ... –

+7

एफ # कहने का वकील होना ठीक है। लेकिन मैंने आपको F # नहीं होने वाली सभी चीज़ों के प्रति शत्रुतापूर्ण होने के लिए लंबे समय तक (यूज़नेट में साल पहले भी) नोट किया है, और फिर भी आपके विस्तार से पता चलता है कि आप नहीं जानते कि आप किस बारे में बात कर रहे हैं। यहां की तरह: आपका तर्क यह प्रतीत होता है कि एक ऐसी भाषा जहां मैं एक प्रोग्राम लिख सकता हूं जो स्टैक ओवरफ़्लो के साथ बंद हो, एक कार्यात्मक नहीं है? लेकिन उन भाषाओं के लिए एक ही तर्क नहीं बनाया जा सकता था जहां मैं ढेर अतिप्रवाह को उकसा सकता हूं? इसलिए, पवित्र एफ # खुद को कार्यात्मक के रूप में नहीं गिना जाएगा। – Ingo

21

स्कैला 2.7.x अंतिम विधियों और स्थानीय कार्यों के स्वयं-पुनरावर्तन (स्वयं को एक फ़ंक्शन कॉल करने) के लिए पूंछ-कॉल अनुकूलन का समर्थन करता है।

स्कैला 2।8 ट्रैम्पोलिन के लिए पुस्तकालय समर्थन के साथ भी आ सकता है, जो पारस्परिक रूप से पुनरावर्ती कार्यों को अनुकूलित करने की एक तकनीक है।

स्कैला रिकर्सन राज्य के बारे में जानकारी का एक अच्छा सौदा Rich Dougherty's blog में पाया जा सकता है।

+0

क्या आप वर्तमान स्कैला स्थिति पर सवाल अपडेट कर सकते हैं? –

+0

@ ओम-नाम-नाम AFAIK, कुछ भी नहीं बदला है, न तो स्कैला पक्ष पर, न ही JVM पक्ष पर। –

0

सभी स्रोत जेएमवी को पूंछ रिकर्सन के मामले में अनुकूलित करने में असमर्थ होने पर इंगित करते हैं, लेकिन Java performance tuning (2003, ओरेली) पढ़ने पर मुझे लेखक ने दावा किया कि वह पूंछ रिकर्सन लागू करके अधिक रिकर्सन प्रदर्शन प्राप्त कर सकता है।

आप पेज 212 पर अपना दावा पा सकते हैं ('पूंछ रिकर्सन' के लिए खोज यह दूसरा परिणाम होना चाहिए)। क्या देता है?

+0

आईबीएम ने अपने जेवीएम कार्यान्वयन में टीसीओ के कुछ रूपों का समर्थन किया है (एक अनुकूलन के रूप में, इसलिए कोई गारंटी नहीं है)। हो सकता है कि जावा परफॉर्मेंस ट्यूनिंग के लेखकों ने सोचा कि अंततः यह सुविधा सभी जेवीएम द्वारा लागू की जाएगी। http://www.ibm.com/developerworks/java/library/j-diag8.html – llemieng