Rust प्रोजेक्ट लक्ष्य: अचल प्रकार और गारंटीकृत destructor

Rust maintainers `!Move` और `!Forget` जैसे नए type-level traits पर विचार कर रहे हैं ताकि immovable types और guaranteed destructors को support किया जा सके, और async, self-referential structures, तथा memory leaks से जुड़ी लंबे समय से चली आ रही समस्याओं को संबोधित किया जा सके। Commenters बताते हैं कि इससे safer structured concurrency संभव हो सकती है (जैसे guaranteed cleanup वाले scoped async tasks) और linear “must-use” resources जैसी अधिक expressive APIs बन सकती हैं, लेकिन साथ ही मौजूदा traits, collections, और `Pin` model के साथ गंभीर backward-compatibility चुनौतियाँ भी हैं। इन features से खुलने वाली क्षमताओं को लेकर व्यापक उत्साह है, लेकिन यह भी स्वीकार किया जाता है कि design जटिल है, अभी final नहीं है, और “pin ergonomics” जैसी alternative proposals के साथ trade-offs कर सकता है.

उच्च-स्तरीय विचार

  • प्रस्ताव !Move, !Forget, और अंततः !Destruct जैसे traits पेश करता है ताकि:
    • अचलता को स्थान के बजाय type का गुण बनाया जा सके (जिससे Pin का बड़ा हिस्सा प्रतिस्थापित होगा)।
    • कुछ types के लिए यह गारंटी दी जा सके कि destructors चलेंगे (या leak करना असंभव होगा)।
    • linear / must-move types के लिए आधार तैयार किया जा सके।

Async Rust और structured concurrency

  • इसका बड़ा प्रेरक बेहतर async/structured concurrency है:
    • आज async tasks को मनमाने ढंग से cancel किया जा सकता है, इसलिए destructors कभी नहीं चल सकते।
    • इससे scoped threads जैसी पूरी तरह सुरक्षित “scoped tasks” बनाना रुक जाता है।
    • !Forget के साथ task handles के drop होने की गारंटी दी जा सकती है, जिससे scoped async सुरक्षित और ergonomic बन सकता है।
  • यह इन मामलों में भी मदद करता है:
    • Recursive async functions (बिना Box::pin जैसी चालों के)।
    • बाहरी scopes से borrow करने वाले async functions, cloning किए बिना।

अचल types बनाम Pin

  • Pin को व्यापक रूप से भ्रमित करने वाला और एक “hack” माना जाता है:
    • यह places को pin करता है और इसमें Unpin semantics तथा projection rules जटिल हैं।
    • Pin का उपयोग करने वाला low-level async code अनergonomic है और unsafe पर निर्भर करता है।
  • !Move अचलता को type का अंतर्निहित गुण बना देगा:
    • self-references और ऐसे जटिल patterns सक्षम करता है जिन्हें Pin पूरी तरह support नहीं कर पाता।
  • एक वैकल्पिक “pinned places”/pin ergonomics मार्ग भी है; यह प्रस्ताव स्पष्ट रूप से एक विकल्प है और दीर्घकाल में Pin को deprecate करने का लक्ष्य रखता है।

Leak control और !Forget

  • !Forget का उद्देश्य यह सुनिश्चित करना है कि storage को फिर से उपयोग करने से पहले destructor चल जाए।
  • mem::forget या ref cycles के जरिए leaks:
    • प्रस्तावित है कि Rc/Arc और समान types के लिए T: Forget की आवश्यकता रखकर इन्हें सीमित किया जाए।
    • Infinite loops या values को अन्य threads पर भेजना “forgetting” नहीं माना जाता, क्योंकि scope कभी समाप्त ही नहीं होता।

Linear / must-move types (!Destruct)

  • यह explicit destruction paths को बाध्य करेगा:
    • transactions जैसी APIs सांख्यिकीय रूप से ठीक एक commit/rollback की मांग कर सकती हैं।
    • “silent rollback” या Drop में panic करने वाले patterns से बचा जा सकेगा।
  • Destruction आम तौर पर defining module में destructuring या dedicated consuming functions की आवश्यकता रखेगा।

Backward compatibility और std पर प्रभाव

  • Backcompat एक बड़ा जोखिम है:
    • मौजूदा generics स्वाभाविक रूप से मानते हैं कि सब कुछ movable और droppable है।
    • Iterator::Item और Deref::Target जैसे traits समस्याग्रस्त हो जाते हैं जब कुछ types !Move हों।
    • Vec<T> जैसी collections मूल रूप से elements को move करती हैं; संभवतः वे !Move types का support नहीं कर पाएँगी, या केवल सीमित APIs के माध्यम से।
  • Editions मदद करती हैं लेकिन सब कुछ हल नहीं कर सकतीं; defaults और bounds (T: Move बनाम T: ?Move) का सावधानीपूर्ण design महत्वपूर्ण और गैर-तथ्यात्मक है।

Algebraic effects और C++ से संबंध

  • कुछ लोग इन traits को effect-like मानते हैं: drop<T>, move<T>, forget<T> functions से जुड़े implicit effects की तरह व्यवहार करते हैं।
  • अन्य लोगों का तर्क है कि यह मुख्यतः type properties और संभावित भविष्य के effect systems के बारे में है।
  • C++ से तुलना:
    • Rust implicit move/copy constructors नहीं जोड़ रहा।
    • अचलता और गारंटीकृत destructors C++ तथा कुछ patterns (self-references, complex object graphs) के साथ interop को आसान बनाते हैं, लेकिन अधिक सख्त और explicit semantics के साथ।

स्थिति और अनिश्चितता

  • यह एक project goal है, स्वीकृत language change नहीं।
  • यह pin-ergonomics लक्ष्य से प्रतिस्पर्धा करता है; कई लोगों को उम्मीद है कि यदि केवल एक बचता है तो immovable types जीतेंगे, लेकिन:
    • यह बदलाव सर्वव्यापी और जटिल है।
    • semantics, backcompat, और std integration अभी भी खुले हैं और design को रोक या काफी बदल सकते हैं।