क्या हास्केल को एक कचरा कलेक्टर की आवश्यकता है?


118

मैं उत्सुक हूं कि हास्केल कार्यान्वयन जीसी का उपयोग क्यों करते हैं।

मैं ऐसे मामले के बारे में नहीं सोच सकता, जहां जीसी शुद्ध भाषा में आवश्यक हो। क्या यह नकल को कम करने के लिए सिर्फ एक अनुकूलन है, या यह वास्तव में आवश्यक है?

मैं उदाहरण कोड की तलाश कर रहा हूं जो अगर जीसी मौजूद नहीं होता तो लीक होता।


14
आपको यह श्रृंखला ज्ञानवर्धक लग सकती है; यह शामिल है कि कचरा कैसे उत्पन्न होता है (और बाद में एकत्र किया जाता है): blog.ezyang.com/2011/04/the-haskell-heap
टॉम

5
शुद्ध भाषाओं में हर जगह संदर्भ हैं! सिर्फ परस्पर संदर्भ नहीं ।
टॉम क्रॉकेट

1
@pelotom डेटा या अपरिवर्तनीय संदर्भों को संदर्भित करता है?
पॉबी

3
दोनों। तथ्य यह है कि जिस डेटा को संदर्भित किया जाता है वह इस तथ्य से अपरिवर्तनीय है कि सभी संदर्भ अपरिवर्तनीय हैं, सभी तरह से नीचे।
टॉम क्रॉकेट

4
आप निश्चित रूप से रुकने की समस्या से दिलचस्पी लेंगे , क्योंकि स्मृति आवंटन के लिए इस तर्क को लागू करने से यह समझने में मदद मिलती है कि सामान्य मामले में व्यवहार की भविष्यवाणी क्यों नहीं की जा सकती है । हालाँकि कुछ ऐसे कार्यक्रम हैं जिनके लिए डीलक्लोकेशन की भविष्यवाणी की जा सकती है, ठीक उसी तरह जैसे वे कुछ प्रोग्राम हैं जिन्हें वास्तव में चलाने के बिना समाप्त करने के लिए जाना जा सकता है।
पॉल आर

जवाबों:


218

जैसा कि दूसरों ने पहले ही बताया है, हास्केल को स्वचालित , गतिशील मेमोरी प्रबंधन की आवश्यकता होती है : स्वचालित मेमोरी प्रबंधन आवश्यक है क्योंकि मैनुअल मेमोरी प्रबंधन असुरक्षित है; गतिशील स्मृति प्रबंधन आवश्यक है क्योंकि कुछ कार्यक्रमों के लिए, किसी वस्तु का जीवनकाल केवल रनटाइम पर निर्धारित किया जा सकता है।

उदाहरण के लिए, निम्नलिखित कार्यक्रम पर विचार करें:

main = loop (Just [1..1000]) where
  loop :: Maybe [Int] -> IO ()
  loop obj = do
    print obj
    resp <- getLine
    if resp == "clear"
     then loop Nothing
     else loop obj

इस कार्यक्रम में, [1..1000]उपयोगकर्ता को "स्पष्ट" होने तक सूची को स्मृति में रखा जाना चाहिए; इसलिए इसका जीवनकाल गतिशील रूप से निर्धारित किया जाना चाहिए, और यही कारण है कि गतिशील स्मृति प्रबंधन आवश्यक है।

तो इस अर्थ में, स्वचालित गतिशील मेमोरी आवंटन आवश्यक है, और व्यवहार में इसका मतलब है: हाँ , हास्केल को एक कचरा कलेक्टर की आवश्यकता है, क्योंकि कचरा संग्रह उच्चतम प्रदर्शन वाला स्वचालित गतिशील मेमोरी मैनेजर है।

तथापि...

यद्यपि एक कचरा संग्रहकर्ता आवश्यक है, हम कुछ विशेष मामलों को खोजने की कोशिश कर सकते हैं जहां संकलनकर्ता कचरा संग्रहण की तुलना में एक सस्ती मेमोरी प्रबंधन योजना का उपयोग कर सकते हैं। मसलन, दिया गया

f :: Integer -> Integer
f x = let x2 = x*x in x2*x2

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

यह पूछने के लिए बहुत अनुचित नहीं है: जेएचसी हैस्केल कंपाइलर ऐसा करता है, हालांकि जीएचसी नहीं करता है। साइमन मार्लो का कहना है कि जीएचसी का जेनेरिक कचरा कलेक्टर ज्यादातर विश्लेषण को अनावश्यक बनाता है।

jhc वास्तव में क्षेत्र विश्लेषण के रूप में ज्ञात एस्केप विश्लेषण के परिष्कृत रूप का उपयोग करता है । विचार करें

f :: Integer -> (Integer, Integer)
f x = let x2 = x * x in (x2, x2+1)

g :: Integer -> Integer
g x = case f x of (y, z) -> y + z

इस मामले में, एक सरलीकृत एस्केप विश्लेषण यह निष्कर्ष निकालता है कि इससे x2बच जाता है f(क्योंकि यह टपल में वापस आ जाता है), और इसलिए x2इसे कचरा एकत्र ढेर पर आवंटित किया जाना चाहिए। दूसरी ओर, क्षेत्र का अनुमान, यह पता लगाने में सक्षम है कि रिटर्न x2होने पर निपटा जा सकता है g; यहाँ विचार यह है कि क्षेत्र के बजाय 'के क्षेत्र x2में आवंटित किया जाना चाहिए ।gf

हस्केल से परे

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

f :: Integer -> Integer
f n = product [1..n]

[1..n]स्टैक पर सूची को आवंटित करने और fरिटर्न के बाद उसे निपटाए जाने के लिए किसी को लुभाया जा सकता है , लेकिन यह भयावह होगा: यह fO (1) मेमोरी (कचरा संग्रह के तहत) से O (n) मेमोरी का उपयोग करने से बदल जाएगा ।

1990 के दशक में और 2000 के दशक की शुरुआत में सख्त कार्यात्मक भाषा एमएल के लिए क्षेत्र में व्यापक कार्य किया गया था । मैड्स टोफ़्टे, लार्स बिर्केडल, मार्टिन एल्समैन, नील्स हॉलबर्ग ने क्षेत्र के अनुमान पर अपने काम पर एक बहुत ही पठनीय पूर्वव्यापी लिखा है , जिसमें से अधिकांश उन्होंने MLKit संकलक में एकीकृत किए । उन्होंने विशुद्ध रूप से क्षेत्र-आधारित स्मृति प्रबंधन (अर्थात कोई कचरा संग्रहकर्ता) के साथ-साथ संकर क्षेत्र-आधारित / कचरा-संग्रहित स्मृति प्रबंधन के साथ प्रयोग किया, और बताया कि उनका परीक्षण कार्यक्रम शुद्ध कचरे की तुलना में "10 गुना तेज और 4 गुना धीमा" के बीच चला। एकत्र किए गए संस्करण।


2
क्या हास्केल को साझा करने की आवश्यकता है? यदि नहीं, तो आपके पहले उदाहरण में, आप सूची की एक प्रति (सम्मान Nothing) पास कर सकते हैं loopऔर पुराने की पुनरावृत्ति के लिए कॉल कर सकते हैं - किसी अज्ञात जीवनकाल को नहीं। बेशक कोई भी हास्केल के गैर-साझाकरण कार्यान्वयन को नहीं चाहता है, क्योंकि यह बड़े डेटा संरचनाओं के लिए बहुत धीमा है।
नीमी

3
मुझे वास्तव में यह उत्तर पसंद है, हालांकि मेरा एकमात्र भ्रम पहले उदाहरण के साथ है। जाहिर है अगर उपयोगकर्ता ने कभी भी "स्पष्ट" टाइप नहीं किया है, तो वह अनंत मेमोरी (बिना जीसी) का उपयोग कर सकता है, लेकिन यह बिल्कुल लीक नहीं है क्योंकि मेमोरी अभी भी ट्रैक की जा रही है।
पॉबी

3
C ++ 11 में स्मार्ट पॉइंटर्स का अद्भुत कार्यान्वयन है। मूल रूप से यह संदर्भ गणना को नियोजित करता है। मुझे लगता है कि हास्केल कचरा संग्रह को कुछ इसी तरह के पक्ष में ले सकते हैं, और इसलिए निर्धारक बन जाते हैं।
इंट्रेपिडिस

3
@ क्रिसनाश - काम नहीं करता। स्मार्ट पॉइंटर्स हुड के नीचे संदर्भ गिनती का उपयोग करते हैं। संदर्भ गणना चक्रों के साथ डेटा संरचनाओं से नहीं निपट सकती है। हास्केल चक्रों के साथ डेटा संरचनाएं उत्पन्न कर सकता है।
स्टीफन सी

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

27

आइए एक तुच्छ उदाहरण लेते हैं। अगर यह दिया रहे

f (x, y)

आपको (x, y)कॉल करने से पहले जोड़ी को कहीं आवंटित करने की आवश्यकता है f। आप उस जोड़ी को कब निपटा सकते हैं? तुम्हें कुछ पता नहीं है। fरिटर्न करते समय इसे निपटाया नहीं जा सकता है , क्योंकि fहो सकता है कि जोड़े को डेटा संरचना (जैसे f p = [p]) में रखा जाए, इसलिए जोड़ी के जीवनकाल को वापसी से अधिक समय तक रहना पड़ सकता है f। अब, यह कहें कि इस जोड़ी को एक सूची में रखा गया था, जो कोई भी इस जोड़ी को अलग करने की सूची ले सकता है? नहीं, क्योंकि जोड़ी को साझा किया जा सकता है (जैसे, let p = (x, y) in (f p, p))। इसलिए यह बताना मुश्किल है कि इस जोड़ी को कब डील किया जा सकता है।

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

इसलिए मैं प्रश्न को चारों ओर मोड़ना चाहूंगा। आपको क्यों लगता है कि हास्केल को जीसी की जरूरत नहीं है। आप स्मृति आवंटन का सुझाव कैसे देंगे?


18

आपका अंतर्ज्ञान कि यह पवित्रता के साथ कुछ करना है, इसके लिए कुछ सच्चाई है।

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

लेकिन एक ऐसा कार्य है जो हास्केल में हर जगह अंतर्निहित रूप से उपयोग किया जाता है और जिसके प्रकार के हस्ताक्षर का कोई मतलब नहीं है, जो कुछ अर्थों में है, एक दुष्प्रभाव। अर्थात् फ़ंक्शन जो कुछ डेटा को कॉपी करता है और आपको दो संस्करण वापस देता है। हुड के तहत यह या तो शाब्दिक रूप से काम कर सकता है, स्मृति में डेटा की नकल करके, या 'वस्तुतः' एक ऋण को बढ़ाकर जिसे बाद में वापस भुगतान करने की आवश्यकता होती है।

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

वास्तव में, हास्केल के एक रिश्तेदार क्लीन , के पास रैखिक (अधिक सख्ती से: अद्वितीय) प्रकार हैं, और यह कुछ विचार दे सकता है कि यह नकल को अस्वीकार करने के लिए क्या होगा। लेकिन क्लीन अभी भी "गैर-अद्वितीय" प्रकारों के लिए कॉपी करने की अनुमति देता है।

इस क्षेत्र में बहुत सारे शोध हैं और यदि आप पर्याप्त Google करते हैं तो आपको शुद्ध रैखिक कोड के उदाहरण मिलेंगे जिनके लिए कचरा संग्रहण की आवश्यकता नहीं है। आपको सभी प्रकार के प्रकार के सिस्टम मिलेंगे जो संकलक को संकेत दे सकते हैं कि क्या मेमोरी का उपयोग किया जा सकता है जो संकलक को कुछ GC को खत्म करने की अनुमति देता है।

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

फोर्थ (या अन्य स्टैक आधारित भाषाओं) के साथ तुलना करना भी दिलचस्प है, जिसमें स्पष्ट रूप से डुप संचालन है जो दोहराव होने पर स्पष्ट करते हैं।

इस बारे में सोचने का एक और (अधिक सार) तरीका यह ध्यान रखना है कि हास्केल को केवल टाइप किए गए लंबो कैलकुलस से बनाया गया है जो कार्टेशियन बंद श्रेणियों के सिद्धांत पर आधारित है और इस तरह की श्रेणियां एक विकर्ण फ़ंक्शन से सुसज्जित हैं diag :: X -> (X, X)। किसी अन्य श्रेणी के वर्ग पर आधारित भाषा में ऐसी कोई बात नहीं हो सकती है।

लेकिन सामान्य तौर पर, विशुद्ध रूप से रैखिक प्रोग्रामिंग उपयोगी होना बहुत मुश्किल है, इसलिए हम GC के लिए व्यवस्थित होते हैं।


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

14

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

यही कारण है कि जीएचसी कार्यक्रमों में ऐसे उच्च कुल आवंटन आंकड़े (गीगाबाइट्स से टेराबाइट्स) होते हैं: वे लगातार मेमोरी आवंटित कर रहे हैं, और यह केवल कुशल जीसी के लिए धन्यवाद है कि वे इसे चलाने से पहले इसे पुनः प्राप्त करते हैं।


2
"वे पिछले मानों को कभी नहीं बदलते हैं ": आप haskell.org/haskellwiki/HaskellImplementorsWorkshop/2011/Takano की जांच कर सकते हैं , यह एक प्रयोगात्मक जीएचसी एक्सटेंशन के बारे में है जो मेमोरी का पुन: उपयोग करता है।
12 gfour

11

यदि कोई भाषा (कोई भी भाषा) आपको वस्तुओं को गतिशील रूप से आवंटित करने की अनुमति देती है, तो स्मृति के प्रबंधन से निपटने के तीन व्यावहारिक तरीके हैं:

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

  2. भाषा एक स्पष्ट freeया disposeतंत्र प्रदान कर सकती है। लेकिन यह सही होने के लिए प्रोग्रामर पर निर्भर करता है। स्टोरेज मैनेजमेंट में कोई गलती होने पर मेमोरी लीक हो सकती है ... या इससे भी बदतर।

  3. भाषा (या अधिक सख्ती से, भाषा कार्यान्वयन) गतिशील रूप से आवंटित भंडारण के लिए एक स्वचालित भंडारण प्रबंधक प्रदान कर सकती है; यानी कूड़ा उठाने वाले का कोई रूप।

एकमात्र अन्य विकल्प गतिशील रूप से आवंटित भंडारण को पुनः प्राप्त नहीं करना है। यह एक व्यावहारिक समाधान नहीं है, छोटे संगणना करने वाले छोटे कार्यक्रमों को छोड़कर।

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

मैं ऐसे मामले के बारे में नहीं सोच सकता, जहां जीसी शुद्ध भाषा में आवश्यक हो।

संभवतः आप एक शुद्ध कार्यात्मक भाषा का मतलब है।

इसका उत्तर यह है कि भाषा के निर्माण के लिए ढेर वस्तुओं को पुनः प्राप्त करने के लिए एक जीसी की आवश्यकता होती है। उदाहरण के लिए।

  • एक शुद्ध फ़ंक्शन को ढेर ऑब्जेक्ट्स बनाने की आवश्यकता होती है क्योंकि कुछ मामलों में इसे उन्हें वापस करना पड़ता है। इसका मतलब है कि उन्हें स्टैक पर आवंटित नहीं किया जा सकता है।

  • तथ्य यह है कि चक्र हो सकता है ( let recउदाहरण के लिए परिणामस्वरूप ) का अर्थ है कि एक संदर्भ गिनती दृष्टिकोण ढेर वस्तुओं के लिए काम नहीं करेगा।

  • फिर फंक्शन क्लोजर हैं ... जिन्हें स्टैक पर भी आवंटित नहीं किया जा सकता है क्योंकि उनके पास एक जीवनकाल है (आमतौर पर) उस स्टैक फ्रेम से स्वतंत्र है जिसमें वे बनाए गए थे।

मैं उदाहरण कोड की तलाश कर रहा हूं जो अगर जीसी मौजूद नहीं होता तो लीक होता।

बस किसी भी उदाहरण के बारे में जिसमें क्लोजर या ग्राफ के आकार की डेटा संरचना शामिल थी, उन परिस्थितियों में लीक हो जाएगी।


2
आपको क्यों लगता है कि आपके विकल्पों की सूची संपूर्ण है? ऑब्जेक्टिव C में ARC, MLKit और DDC में रीजन इंट्रेंस, मरकरी में कंपाइल-टाइम कचरा कलेक्शन - ये सभी इस लिस्ट में फिट नहीं होते हैं।
डी मोन

@DeeMon - वे सभी उन श्रेणियों में से एक में फिट होते हैं। अगर आपको लगता है कि वे ऐसा नहीं करते हैं, क्योंकि आप श्रेणी की सीमाओं को बहुत कसकर चित्रित कर रहे हैं। जब मैं कहता हूं "कचरा संग्रहण का कोई रूप", मेरा मतलब है कि कोई भी तंत्र जिसमें भंडारण स्वचालित रूप से पुनः प्राप्त होता है।
स्टीफन सी

1
C ++ 11 स्मार्ट पॉइंटर्स का उपयोग करता है। मूल रूप से यह संदर्भ गणना को नियोजित करता है। यह नियतात्मक और स्वचालित है। मैं हास्केल के इस तरीके का उपयोग देखना पसंद करूंगा।
अंतःस्रावी

2
@ क्रिस - 1) यह काम नहीं करेगा। यदि आप साइकिल हैं तो रेफरेंस काउंट-बेस रिक्लेमेशन डेटा लीक कर देता है ... जब तक आप साइकिल को तोड़ने के लिए एप्लिकेशन कोड पर भरोसा नहीं कर सकते। 2) यह अच्छी तरह से जाना जाता है (जो लोग इन चीजों का अध्ययन करते हैं) जो कि आधुनिक (वास्तविक) कचरा कलेक्टर के साथ तुलना करने पर संदर्भ गिनती खराब प्रदर्शन करती है।
स्टीफन सी

@DeeMon - इसके अलावा, रीसेनप का जवाब इस बात पर है कि हस्केल के साथ रीजन इन्वेंशन व्यावहारिक क्यों नहीं होगा।
स्टीफन सी

8

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


यह जवाब देता है कि जीसी सामान्य रूप से अनावश्यक क्यों है, लेकिन मुझे विशेष रूप से हास्केल में अधिक दिलचस्पी है।
पबबी

10
यदि एक जीसी सैद्धांतिक रूप से सामान्य रूप से अनावश्यक है, तो यह तुच्छ रूप से निम्नानुसार है कि यह हास्केल के लिए भी सैद्धांतिक रूप से अनावश्यक है।
एहर्ड

@ehird मैं कहता हूँ के लिए होती आवश्यक , मुझे लगता है कि मेरी वर्तनी परीक्षक अर्थ फ़्लिप।
पॉबी

1
एहर्ड टिप्पणी अभी भी :-)
पॉल आर

2

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

वैसे भी, यदि आप मुझ पर विश्वास नहीं करते हैं, तो केवल एफपी भाषा को लागू करने का प्रयास करें और आप देखेंगे कि मैं सही हूँ।

संपादित करें: मैं भूल गया था। आलस्य GC के बिना HELL है। मुझे विश्वास नहीं है? उदाहरण के लिए, सी ++ के बिना बस इसे आज़माएं। आप देखेंगे ... चीजें


1

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

इसलिए, यदि आप अपनी भाषा को आलोकियों के माध्यम से लागू करते हैं, तो आपने अंतिम समय तक ऑब्जेक्ट लाइफटाइम्स के बारे में सभी तर्क को स्थगित कर दिया है, जो कि रनटाइम है। चूंकि अब आपको जीवनकाल के बारे में कुछ भी नहीं पता है, केवल एक चीज जो आप यथोचित रूप से कर सकते हैं वह है कचरा इकट्ठा करना ...


1
कुछ मामलों में स्थैतिक विश्लेषण उन थंक कोड में सम्मिलित हो सकता है जो थंक के मूल्यांकन के बाद कुछ डेटा को मुक्त करता है। डीलक्लबेशन रनटाइम पर होगा लेकिन यह जीसी नहीं है। यह C ++ में संदर्भ गिनने वाले स्मार्ट पॉइंटर्स के विचार के समान है। ऑब्जेक्ट लाइफटाइम के बारे में तर्क वहां रनटाइम में होता है लेकिन कोई GC उपयोग नहीं किया जाता है।
डी मोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.