1 पॉइंट द्वारा GN⁺ 2024-09-27 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Rust memory safety और performance, algebraic types, तथा Cargo की खूबियों के बावजूद इस चिंता से शुरू होता है कि stable channel पर भाषा का evolution धीमा हो गया है और यह “अभी पूरा न हुआ first-generation product” जैसा महसूस होता है
  • community बड़ी होने के बाद consensus-based decision making bottleneck बन गया, और coroutines जैसी features, implementation होने के बावजूद, stable Rust में लंबे समय तक इस्तेमाल नहीं की जा सकने वाली चीज़ों के रूप में जमा होती जा रही हैं
  • काल्पनिक “seph edition” का विचार मौजूदा Rust और Cargo ecosystem को बनाए रखते हुए भी breaking change की अनुमति देकर effect system, compile-time permissions, struct field borrow, comptime आदि को experiment करने का है
  • supply chain risk घटाने के लिए file write, network, FFI, unsafe जैसी sensitive features पर capability लगाई जानी चाहिए और caller को उन्हें explicit रूप से allow करना चाहिए
  • ज़्यादातर proposals मौजूदा Rust के साथ compatible नहीं हैं, और केवल capability जोड़ने पर भी semver compatibility तोड़ने वाली नई failure conditions बनेंगी, इसलिए नई edition या compiler fork की जरूरत होगी

Rust “first-generation product” जैसा क्यों महसूस होता है

  • शुरुआत में Rust algebraic types, performance loss के बिना memory safety, और modern package manager की वजह से बहुत आकर्षक भाषा लगी
  • लगभग 4 साल इस्तेमाल करने के बाद भाषा “हमेशा थोड़ी अधूरी” स्थिति में रुकी हुई लगती है
  • मुख्य शिकायत यह है कि stable Rust में नई features आने की frequency घट गई है, और language evolution की speed भी काफी धीमी हो गई है
  • Rust unstable book में करीब 700 unstable features हैं, जिनमें से काफी standard library changes हैं
  • Coroutines ऐसी feature है जिसका RFC 7 साल पुराना है और compiler में implemented है, लेकिन stable Rust users अभी भी इसे इस्तेमाल नहीं कर सकते
  • Rust RFC process अच्छे ideas के लंबे समय तक अटके रहने की जगह जैसा दिखता है
    • Mutex improvement discussion का उदाहरण दिया गया है, जहां 25 लोगों ने 2 साल में 200 से ज्यादा comments छोड़े, लेकिन कोई स्पष्ट निष्कर्ष नहीं निकला

काल्पनिक “seph edition” का विचार

  • कल्पना यह है कि compiler को fork किया जाए, लेकिन मौजूदा Rust code को वैसा ही रहने दिया जाए और अलग Rust edition के रूप में “seph” जोड़ा जाए
  • इस edition में breaking change की अनुमति होगी, और अगर compiler mainline Rust को compile करता रह सके तो Cargo के मौजूदा crates का इस्तेमाल जारी रखा जा सकता है
  • जिन बड़े axes को बदलना है, वे पांच हैं
    • function traits और effect system
    • compile-time capability
    • Pin, move, और struct borrow redesign
    • Zig-style comptime
    • syntax और standard library में छोटे improvements

function traits और effect system

  • Rust में structs के लिए traits हैं, लेकिन proposal यह है कि functions पर भी ज्यादा समृद्ध trait/effect लगाए जा सकने चाहिए
  • function की possible properties को इस तरह व्यवस्थित किया गया है
    • panic हो सकता है या नहीं
    • fixed stack size है या नहीं
    • अंत तक run होता है या yield/await करता है
    • coroutine होने पर continuation type
    • pure function है या नहीं
    • indirectly unsafe code execute करता है या नहीं
    • termination guarantee है या नहीं
  • अगर function के parameters और return type को function के associated types की तरह expose किया जाए, तो अभी stable Rust में असंभव type references संभव हो जाएंगे
  • उदाहरण some_iter::Output की तरह function return type को सीधे नाम देकर struct field में डालने वाले code का है
  • Linux kernel जैसे cases में जब यह guarantee चाहिए कि कोई specific code block कभी panic नहीं करेगा, तो #[disallow(Panic)] जैसे marker से recursive calls सहित panic possibility check की जा सकती है
  • compiler पहले से Fn, FnOnce, FnMut जैसे function-related traits handle करता है, लेकिन मौजूदा form को बहुत कमजोर माना गया है
  • ज्यादा detail के लिए Yoshua Wuyts का effect system article और talk linked है

compile-time capability से supply chain risk कम करना

  • अधिकतर Rust projects कई third-party crates लाते हैं, और छोटी utility crate भी malicious update के जरिए supply chain risk पैदा कर सकती है
  • memory safety में जैसे unsafe explicit opt-in है, वैसे ही file system, network, FFI, raw pointer से जुड़ी sensitive features को भी explicit रूप से allow करना चाहिए
  • standard library की security-sensitive functions पर marker tag लगाने का तरीका propose किया गया है
    • उदाहरण: std::fs::write(path, contents) arbitrary path पर file लिखता है, इसलिए इसका #[cap(fs_write)] जैसा tag होगा
    • compiler उस function को call करने वाले पूरे call tree को automatically taint करेगा
  • अगर third-party crate को fs_write capability चाहिए, तो caller को Cargo.toml या call-site annotation के जरिए explicit रूप से allow करना होगा
  • allow न करने पर compiler error दे सकता है कि foo::do_stuff() local file system पर write करता है, लेकिन foo crate को उस capability के लिए trusted नहीं माना गया
  • human-size या serde जैसी कई utility crates को special capability की जरूरत नहीं होती, इसलिए author malicious code जोड़ भी दे तो file write या network activity को compile stage पर रोका जा सकता है
  • विकल्प के रूप में sensitive API को अलग Capability parameter लेने के लिए बदलने का तरीका भी है
    • उदाहरण: std::fs::write को FsWriteCapability value चाहिए
    • Capability object बनाना केवल root crate में संभव होने तक सीमित किया जाए
  • इस तरीके में boilerplate बढ़ेगा, लेकिन यह ज्यादा flexible है, और build.rs scripts तथा unsafe blocks पर भी समान treatment चाहिए
  • crates.io hack होकर serde में cryptolocker code आने की स्थिति में भी capability approach में वह code कई developer machines पर run होने या binary में शामिल होने से पहले compile error दे देगा

Pin, move, और struct borrow redesign

  • Pin को borrow checker की कमी को bypass करने वाला complex hack और backward compatibility बनाए रखने से बना band-aid माना गया है
  • राय है कि असल में जरूरत movable types को mark करने वाले Move marker trait जैसी चीज़ की है
  • मौजूदा Rust में Pin trait नहीं है, बल्कि Unpin और !Unpin हैं, और double negative form concept को और कठिन बना देता है
  • आलोचना है कि Pin केवल reference types पर apply होता है, इसलिए जगह-जगह Box में wrap करने वाला code बनता है
    • उदाहरण के तौर पर Tokio stream wrapper, ouroboros, async-trait, self_cell जैसी helper libraries linked हैं
  • Future::poll(self: Pin<&mut Self>, ..) जैसी pinned value लेने वाली functions भी complex हो जाती हैं, और projection handle करने के लिए अलग crate चाहिए
  • function के अंदर borrow checker variables को “owned”, “borrowed”, “mutably borrowed” states में manage करता है, लेकिन ये states programmer को सीधे नहीं दिखतीं
  • async fn में compiler hidden struct बनाकर suspension state store करता है, और तब एक field दूसरे field को borrow कर सकता है
  • Rust में यह express करने की syntax नहीं है कि struct field borrowed state में है, और fields के बीच lifetime भी directly express नहीं किया जा सकता
  • proposed direction borrow checker को extend करके struct field borrow सीधे लिखने लायक बनाने की है
    • उदाहरण: y: &'Self::x Vec<usize> जैसी “local borrow” syntax
    • compiler को पता होगा कि x borrowed है और function के अंदर borrowed variable जैसी constraints लागू करेगा
  • ऐसी syntax self-referential struct या AST में source: String और ast_nodes: Vec<&'Self::source str> जैसे forms handle करने में भी इस्तेमाल हो सकती है
  • borrowed field वाली struct movable नहीं होगी, इसलिए वह Move implement नहीं करेगी, और आगे चलकर खुद को safely move करने वाला Mover trait भी consider किया गया है

Zig-style comptime और Rust macro problem

  • Rust compiler व्यावहारिक रूप से Rust, Rust macro language, और proc macro सहित कई languages को साथ handle करने वाली structure जैसा दिखता है
  • मुख्य assessment यह है कि Rust खुद अच्छी है, लेकिन macro language अच्छी नहीं है
  • Zig का comptime compiler द्वारा एक छोटे interpreter के जरिए code के कुछ हिस्सों को compile time पर execute करने का तरीका है
  • functions, parameters, if, loop को compile-time code के रूप में mark किया जा सकता है, और non-comptime code actual program में emit होता है
  • Zig का std print case study format string को comptime parameter के रूप में लेकर, comptime loop में parse कर output code generate करने का example है
  • Rust का println!() implementation format_args_nl जैसी internal function call करता है, और अनुमान है कि यह function compiler में hardcoded है
  • इसके बाद आलोचना आती है कि Rust compiler authors भी Rust macro language इस्तेमाल नहीं करना चाहते लगते हैं

syntax और standard library में छोटे fixes

  • Range<T> का T: Copy होने पर Copy implement करने वाला issue fix करना चाहने की बात है
  • associated type वाले derive issue को भी fix target माना गया है
  • proposal है कि if let expressions को logical AND support करना चाहिए
    • desired form: if let Some(x) = some_var && some_expr { }
    • current workaround (some_var, check_foo()) tuple matching है, लेकिन some_var के None होने पर भी check_foo() execute होता है, जो सामान्य if के short-circuit behavior से अलग है
    • example: Playground
  • raw pointer ergonomics को भी improvement target माना गया है
    • references में myref.x लिखा जा सकता है, लेकिन pointer में (*myptr).x या (*(*myptr).p).y जैसा लिखना पड़ता है
    • stance है कि unsafe code जितना हो सके पढ़ने-लिखने में आसान होना चाहिए
  • built-in collection type को global allocator के बजाय constructor में explicitly Allocator लेने के लिए बदलना चाहने का proposal है
  • async को भी improvement चाहिए, लेकिन उसे अलग article जितना बड़ा topic बताकर छोड़ा गया है

compatibility और feasibility

  • अधिकांश proposals मौजूदा Rust के साथ compatible नहीं हैं
  • security capability जोड़ना भी crate के लिए semver compatibility तोड़ने वाली नई तरह की failure condition बनाता है, इसलिए नई Rust edition चाहिए
  • कुछ साल पहले होते तो शायद RFC लिखा जाता, लेकिन लंबे GitHub RFC comment process से गुजरकर एक और unrealized idea बन जाने की स्थिति से बचना चाहते हैं
  • आखिरकार compiler को सीधे fork करने की कल्पना पर लौटते हैं, लेकिन practical constraint यह है कि करने के लिए पहले से बहुत सारे projects हैं

1 टिप्पणियां

 
GN⁺ 2024-09-27
Hacker News की टिप्पणियाँ
  • इस बात के उलट कि Rust RFC प्रक्रिया अच्छे विचारों की कब्रगाह है, मुझे लगता है कि Rust core team का programming language में नए features जोड़ना मुश्किल बनाना सही दिशा है
    भाषा की सतह को बहुत भारी, असंगत और अप्रत्याशित होने से रोकना चाहिए। Swift भी मुझे शुरुआत में पसंद था, लेकिन isMultiple(of:) जैसे दोहराव वाले function names, SwiftUI के लिए curly braces parsing rules, reference/value types और mutability rules, closure arguments की shorthand notation वगैरह लगातार बढ़ते गए और आखिरकार मैंने छोड़ दिया। अच्छे विचार आम हैं, इसलिए चाहता हूँ कि Rust जितना हो सके lean रहे

    • मैं मूल पोस्ट का लेखक हूँ। Rust इस्तेमाल करते समय अक्सर ऐसा होता है कि feature X और feature Y अलग-अलग तो supported हैं, लेकिन साथ में इस्तेमाल न हो पाने वाली खाइयाँ हैं
      उदाहरण के लिए, impl Trait लौटाने वाला function इस्तेमाल किया जा सकता है और struct में मनचाहे fields हो सकते हैं, लेकिन impl Trait से लौटाई गई value को struct field में नहीं रखा जा सकता। क्योंकि type को नाम नहीं दिया जा सकता। if a && b और if let Some(x) = x चलते हैं, लेकिन if let Some(x) = x && b नहीं चलता। ऐसी चीजें सुधरनी चाहिए। compiler code की lines के हिसाब से Rust बड़ा होगा, लेकिन सीखने और इस्तेमाल की जटिलता के हिसाब से ऐसे feature gaps उल्टा भाषा को और जटिल बनाते हैं। Pin को standard library में implement करना कोई बहुत बड़ा काम नहीं था, लेकिन यह बिल्कुल भी lean feature नहीं है और cognitive burden बहुत ज्यादा है। मेरे हिसाब से simple compiler और इस्तेमाल में मुश्किल भाषा की बजाय, complex borrow checker और पढ़ने में आसान Rust code बेहतर है
    • RFC लिखना उसे implement करने से आसान है, और RFC लिख सकने वाले लोग भी ज्यादा हैं। इसलिए किसी भी popularity level पर RFC queue अच्छे विचारों की कब्रगाह जैसी दिखना तय है
      भले ही queue में पड़े ideas 100% accept होकर आखिरकार उन पर काम हो जाए, incoming और outgoing गति के फर्क की वजह से वह ऐसा ही दिखता है। अगर आप RFC authors से आगे निकलना चाहते हैं, तो RFC न लिखें; documentation और tests के साथ production-ready implementation बनाएं, जिसे tree में साफ-सुथरे तरीके से merge किया जा सके
    • मोटे तौर पर सहमत हूँ, लेकिन traits के generic associated constants stable होने के बावजूद उन्हें असली constants की तरह इस्तेमाल न कर पाने की विरोधाभासी स्थिति है
      उन्हें न तो दूसरे type के const generic के रूप में, न ही array length के रूप में इस्तेमाल कर सकते हैं। अगर बस value चाहिए, तो function define करके return कर सकते हैं, इसलिए फिलहाल यह ज्यादा उपयोगी नहीं है। सही support मिल जाए तो cryptography libraries में generic_array, typenum जैसे helper crates हटाए जा सकते हैं। फिर भी मैं सहमत हूँ कि Rust team को features जोड़ने में सावधान रहना चाहिए
    • Rust पहले से ही कुछ हद तक mainstream programming languages में Wagyu जैसी स्थिति में है, इसलिए इतना fat और नहीं जोड़ना चाहिए कि खाया ही न जा सके
    • अच्छे विचार परिभाषा के हिसाब से दुर्लभ और कीमती होते हैं
  • निर्भरता की स्थिति काफ़ी गंभीर है, लेकिन लगता है कि इसे मानने वाले लोग बहुत कम हैं। हाल में देखा गया उदाहरण cargo-watch crate है
    मूल रूप से यह फ़ाइल में बदलावों पर नज़र रखने और compiler को फिर से चलाने वाला एक साधारण app है, और implementation 1,000 lines से भी कम है। लेकिन dependencies को vendor करने पर Rust code 8,000 से ज़्यादा files में फैलकर लगभग 40 लाख lines तक बढ़ जाता है। एक साधारण file watcher के हिसाब से यह ज़्यादा है
    https://crates.io/crates/cargo-watch

    • transitive dependencies बनाना आसान हो, और “library है तो उसे ज़रूर इस्तेमाल करना चाहिए” जैसी संस्कृति हो, तो नतीजा अनिवार्य रूप से यही होता है
      C/C++ व्यापक रूप से इस्तेमाल होने वाली भाषाओं में लगभग अकेला उदाहरण है जहाँ npm-शैली का package manager लोकप्रिय नहीं है, इसलिए ज़्यादातर libraries self-contained होती हैं या उनकी dependencies कम और अक्सर optional होती हैं। efsw बिना dependency वाला 7,000-line का C++ file system watcher है। game programming की single-header libraries stb_*, cgltf, और Dear ImGui मेरे इस्तेमाल किए हुए सबसे सुखद अनुभवों में थीं। मुझे लगता है कि नए package manager में transitive dependencies पर रोक कुल मिलाकर फायदेमंद हो सकती है। बड़ी library dependencies users से सीधे install करवाई जा सकती हैं, callbacks दिए जा सकते हैं, या उन्हें standard feature बनाया जा सकता है
      https://github.com/SpartanJ/efsw
      https://github.com/nothings/stb
      https://github.com/jkuhlmann/cgltf
      https://github.com/ocornut/imgui
    • आजकल dependency jungle ही काम पूरा करने का आम तरीका है। runtime जो सबसे अच्छा कर सकता है, वह है इसे स्वीकार करना, इसे जितना संभव हो तेज़ और सुरक्षित बनाना, और standard library को फैलाकर न्यूनतम-dependency projects को भी support करना
      file watcher, ख़ासकर जब कई platforms support करने हों, मुझे तो बिल्कुल भी सरल नहीं लगता
    • यह स्वाभाविक और बहुत डरावना नहीं है। हर code अपने इस्तेमाल से कहीं ज़्यादा functionality वाली dependencies की पर्वत-श्रृंखला पर खड़ा होता है
      cargo watch का एक हिस्सा Win32 API wrapper library लाता है, जो Win32 calls के लिए auto-generated bindings हैं, इसलिए उसका विशाल होना तय है। अधिकांश भाषाओं की standard libraries भी लाखों lines की होती हैं, और apps उनमें से केवल कुछ हिस्से इस्तेमाल करते हैं। C++ का Boost भी राक्षसी रूप से बड़ा है, लेकिन developers उसके कुछ extensions ही इस्तेमाल करते हैं। बल्कि isOdd या is even जैसे किसी single package से ecosystem बिगाड़ सकने वाले npm-शैली के नरक की तुलना में, कम संख्या में ऐसी बड़ी dependencies बेहतर हैं जिन्हें कई लोग maintain करते हैं और जिन पर निर्भर करते हैं; Rust कुल मिलाकर उसी तरफ़ ज़्यादा है
    • काम पर हम जानबूझकर कई dependencies हटाकर फिर से लिखते हैं, लेकिन 1,000 lines हों या 40 लाख lines, इस project के लिए उचित code lines के अनुमान के तौर पर दोनों ही गलत लगते हैं
      cargo-watch की अधिकांश dependencies शायद तीन direct requirements clap, cargo_metadata, watchexec से आती हैं। clap platform-specific CLI elements बहुत खींच लाता है, और cargo_metadata को serde family की बहुत सारी चीज़ें लानी ही पड़ती हैं। watchexec में सुधार की गुंजाइश है; यह उसी संगठन द्वारा maintain किए जाने वाले command-group पर निर्भर है, और वह बिना शर्त Tokio मांगता है। बड़ा मुद्दा यह है कि दूसरे crates की अत्यधिक dependencies को आसानी से ठीक नहीं किया जा सकता। अगर कोई crate पुराने watchexec से बंधा है, तो कभी-कभी Cargo.lock adjust करके काम चल सकता है, लेकिन आम तौर पर मुश्किल होता है और [patch] से workaround करना पड़ता है। किसी खास version के crate को बदलने के लिए “stand-in” आसानी से define करने का तरीका हो तो अच्छा होगा, लेकिन मौजूदा package managers के लिए यह बड़ा research problem लगता है
    • ज़्यादातर line count संभवतः generated Windows API crates से आया होगा। ये कुख्यात रूप से विशाल होते हैं
  • Rust अब कोई रोमांचक नई भाषा नहीं रही; यह व्यापक adoption की ओर बढ़ने वाला चरण है। feature development का धीमा होना स्वाभाविक और स्वस्थ है
    इस समय design mistakes, धीमी गति से कहीं ज़्यादा नुकसानदेह हैं। Rust इसलिए दिलचस्प नहीं है कि उसमें शानदार features हैं, बल्कि इसलिए कि यह memory-safe, garbage collection के बिना, production-ready भाषाओं की एक नई श्रेणी है। महत्वपूर्ण जगहों पर इसका वास्तविक adoption, भाषा को और बेहतर बनाने से ज़्यादा दिलचस्प है, और सावधानी से संचालन होने का भरोसा हो तो यह आसान होता है

    • JavaScript को भी समान life stage में माना जा सकता है, लेकिन पिछले 10 वर्षों में इसमें बेहतरीन नए features की भरमार जुड़ी है
      spread operator, generator functions, async, arrow functions, leftpad, नया Date—महत्वपूर्ण features की सूची खत्म ही नहीं होती। JS, Rust से कहीं पुरानी और कहीं ज़्यादा व्यापक रूप से इस्तेमाल होने वाली भाषा है, और इसके कई production implementations हैं, इसलिए सभी नए features को मिलाकर implement करना पड़ता है। ES5 के आसपास ठहराव का दौर था, लेकिन फर्क शायद इस बात में दिखता है कि ECMAScript standards committee ने खुद को संभाल लिया
    • Ada/SPARK तो बहुत पहले से था, इसलिए संदेह है कि यह सचमुच भाषाओं की नई श्रेणी है या नहीं। SPARK तो safety को formal verification तक ले जाता है
  • Rustaceans हर चीज़ को Rust में दोबारा लिखने को लेकर इतने obsessed हैं कि सच में लगा था कि Rust को दोबारा लिखने वाला लेख कोई meta-satire joke होगा

    • यह तो prehistoric दौर में ही हो चुका था। मूल Rust OCaml में लिखा गया था, लेकिन आखिरकार उसे Rust में फिर से लिखा गया
    • मैं original post का author हूँ। title में इशारा उसी reference की ओर था
    • वे चाहते हैं कि आप लोग, या हम, हर चीज़ Rust में फिर से लिखें। खुद वे नहीं
    • programming languages वाले लोग bootstrapping भी पसंद करते हैं। Rust को Rust में लिखना इतना बेतुका नहीं है
  • पहले धीले decision-making की शिकायत करना और फिर stable न हो पाने की वजह के तौर पर ऐसी features की सूची देना जिनका decision-making से ज़्यादा लेना-देना नहीं है, थोड़ा अजीब है
    उदाहरण के लिए coroutines कुछ ऐसे edge cases की वजह से अटकी हुई हैं जिन्हें ठीक से हल करना मुश्किल है। compiler के अंदर ऐसा कोई पूरा implementation नहीं है जिसे “बस on कर दें”; बल्कि यह एक अधूरा implementation है जो कई मामलों में काम करता है, लेकिन stable version में enable नहीं किया जा सकता। function traits को भी कई technical वजहों और भविष्य की features के साथ उनके interaction के कारण मौजूदा रूप में stabilize न करने का स्पष्ट decision लिया गया है। अतीत में लौटें तो कुछ हिस्से अलग तरह से design किए जा सकते थे, लेकिन ज़्यादातर फैसले Rust के शुरुआती दिनों से जुड़े हैं, जब team और resources बहुत छोटे थे। आज बेहतर choices कर सकते हैं, इसलिए Rust 2.0 जैसा breaking बदलाव लाया जाए—ऐसा विचार हो सकता है, लेकिन Python 2 से 3 पर migration की तबाही इतनी बड़ी थी कि बहुत से लोग rough edges सह लेना बेहतर मानते हैं। Rust weekly newsletter देखें तो RFC approvals और stabilization decisions हर हफ्ते process हो रहे हैं। कुछ मामलों में बहुत ज़्यादा समय लगता है, लेकिन people, coordination और time की कमी वाली समस्याएँ अक्सर technical समस्याओं से ज़्यादा कठिन होती हैं

  • इस लेख को Josh Triplett के Reddit जवाब के साथ भी पढ़ना चाहिए। लेख के मुख्य examples में से एक Mutex बस गलत है
    https://old.reddit.com/r/rust/comments/1fpomvp/rewriting_rus...
    संशोधन: वही comment यहाँ भी है
    https://news.ycombinator.com/item?id=41655268

  • Rust सीखते समय सबसे पहले मुझे यह लगा कि कल्पना की जा सकने वाली लगभग हर feature इसमें पहले से मौजूद है
    इसका मतलब यह नहीं कि Rust team ने कभी किसी चीज़ को reject नहीं किया, फिर भी लोग और ज़्यादा features चाहते हैं। कुछ मांगें वाजिब हैं, लेकिन कुछ ऐसी लगती हैं जैसे कोई feature जिसे केवल 2% developers इस्तेमाल करेंगे, उसे ऐसी language में ज़रूर जोड़ना चाहिए जिसे सिर्फ 1% developers समझते हैं। एक complex language को और complex होने की ज़रूरत नहीं है। Zig ज़्यादा सरल है, शायद ज़्यादा तेज़ भी, और community drama भी काफी कम है। काश Zig को ज़्यादा funding मिले

    • आपको यह जानकर हैरानी हो सकती है कि random लोगों द्वारा propose की गई काफी features Rust community में reject हो जाती हैं
      Rust हर संभव feature जोड़ने की कोशिश नहीं कर रहा। बस GAT या TAIT जैसी चीज़ें अगर यह साफ़ जाने बिना दिखें कि वे कौन-सी समस्या हल करती हैं, तो ऐसा लग सकता है। Zig एक अच्छी modern language हो सकती है, लेकिन अगर लक्ष्य memory safety है तो वह विकल्प नहीं है
    • मैं original article का लेखक हूँ। मुझे लगता है कि Rust का complexity budget कई गलत जगहों पर खर्च हो रहा है
      उदाहरण के लिए Pin और futures का interaction language में बेतुकी complexity जोड़ता है, और मुझे लगता है कि उसका कुछ हिस्सा अनावश्यक है। काश Rust जैसी कोई language होती जिसमें Pin बिल्कुल न होता। borrow checker को भी syntax और implementation दोनों तरफ से simplify करने के तरीके हो सकते हैं, हालांकि मैंने अभी उस पर ठोस रूप से नहीं सोचा है। फिलहाल language को fork किए बिना इसे बदलना मुश्किल होगा, लेकिन borrow checker इस्तेमाल करने वाली language के रूप में Rust आख़िरी नहीं होगी। उम्मीद है कि अगली generation में और बड़ी language बनाए बिना भी सुधार की काफी गुंजाइश होगी
    • ज़्यादा funding आने से गलत किस्म के लोग आकर्षित हो सकते हैं। उनकी खराबी और नुकसान पहुँचाने की क्षमता कभी-कभी बहुत देर से सामने आती है
    • मुझे जानना है कि Rust community के किस drama की बात हो रही है
      Rust से जुड़े dramas दिखते हैं, लेकिन आम तौर पर वे Rust के इस्तेमाल या adoption का विरोध करने वालों की तरफ से पैदा होते हैं। जैसे हाल का Rust for Linux हंगामा। community के अंदर यह आम बात नहीं लगती, हालांकि हो सकता है मैंने कुछ miss किया हो। Zig शानदार है, लेकिन अभी production ready नहीं है
    • nightly में दबी हुई features की कब्रगाह सच में काफी बड़ी है। specialization जैसी महत्वपूर्ण feature भी हमेशा से वहीं stuck पड़ी है
  • लिंक किए गए comment के लेखक ने कई भाषाओं के synchronization primitives का व्यापक विश्लेषण करने के बाद, Rust के Mutex और RwLock जैसे synchronization primitives को इस तरह फिर से लिखा कि हर प्रमुख operating system पर वे सीधे नीचे के OS primitives का इस्तेमाल करें
    Linux के futex जैसी चीज़ों का इस्तेमाल करके उन्हें तेज़, छोटा और कुल मिलाकर बेहतर बनाया, और इस प्रक्रिया में Rust parallel programming पर लगभग एक किताब भी लिख डाली। यह Rust के अलावा parallel programming के लिए भी उपयोगी है
    https://www.oreilly.com/library/view/rust-atomics-and/978109...
    ऐसा भी नहीं कि 7 साल तक coroutine क्षेत्र में बस खेलते ही रहे। async functions, ऐसे traits जो async functions शामिल कर सकते हैं, AsyncWrite और AsyncRead को standardize करने के लिए ज़रूरी कई features जोड़े गए, और nightly में generator implementation भी है। इस पर चर्चा चल रही है कि पूरी तरह general coroutines की complexity उठाई जाए या generators पर ही रुका जाए। AsyncIterator जैसे कुछ features धीमे हैं, लेकिन सक्रिय काम भी बहुत हो रहा है। यह हमेशा दिलचस्प लगता है कि एक तरफ लोग कहते हैं भाषा बहुत धीमी है, और दूसरी तरफ शिकायत होती है कि बहुत तेज़ है
    function traits और effect system पर भी हाल में बड़ा design exploration हुआ है, और वे ऐसा समाधान लाना चाहते हैं जिससे async, try, const के हर combination के लिए functions कई बार न लिखने पड़ें। malicious crates की sandboxing भाषा-स्तर की समस्या नहीं है; इसके लिए verifier और runtime sandbox के combination की ज़रूरत है, और WebAssembly components ज़्यादा संभावनाशील दिखते हैं। हालांकि allocator या async runtime चुनने, 64-bit platform assumption जैसी compile-time capabilities में काफी रुचि है, और proc macro sandboxing वे malicious behavior रोकने के लिए नहीं बल्कि सही caching के लिए चाहते हैं
    self-referential structs syntax की समस्या नहीं, बल्कि borrow checker के लिए handle करना बेहद कठिन समस्या है। partial borrow closure capture में पहले से supported है, लेकिन इसे public API में expose करते समय stable semantic versioning कैसे बनाए रखें, यही मुख्य मुद्दा है। नाम वाले “borrow group” जैसा तरीका मजबूत उम्मीदवार है। comptime पर भी कई दिशाओं में काम चल रहा है, और macro_rules को मजबूत करने वाला RFC भी हाल ही में लिखा गया है। Range का impl edition के जरिए incompatible changes से जुड़कर पहले से आगे बढ़ रहा है। if let और logical AND को combine करने वाला unstable feature है और stabilization के करीब है। pointer field access syntax सुधारने के कई proposals भी रहे हैं, लेकिन language surface को और बढ़ाना फायदा है या नुकसान, यह खुला सवाल है। Rust editions की वजह से अगर design पर्याप्त रूप से convincing हो तो बहुत कुछ बदला जा सकता है। 700 unstable features सचमुच समस्या हैं, इसलिए जिनके stabilize होने की संभावना कम है उन्हें साफ़ करने के लिए बड़ा काम चाहिए

    • standard library स्तर के basic packages का development ऐसे ही होना चाहिए। जो भाषाएँ हम आज इस्तेमाल कर रहे हैं वे आने वाले कई दशकों तक इस्तेमाल होंगी, और अगर अभी धीमे लेकिन अच्छे decisions लिए जाएँ तो आगे चलकर बहुत अधिक समय बचेगा
    • proc macro और build script sandboxing पर काफी चर्चा हुई है
      ज़्यादा declarative macros, -sys crate logic को shared libraries पर delegate करना, cfg(version) / cfg(accessible) user implementations की ज़रूरत को काफी घटाएँगे, लेकिन runtime फिर भी बचा रहेगा। जितना सोचता हूँ, cackle की ACL proc macro, build scripts और runtime code पूरे में काम को track करने और dependency tree के इस्तेमाल को audit करने के लिए scalable तरीका लगती है। सुना है cargo-redpen भी call audit tool के रूप में विकसित हो रहा है, लेकिन मैं cackle जैसा और higher-level कुछ सोच रहा हूँ
      https://github.com/cackle-rs/cackle
    • मैं original post का लेखक हूँ। अंदरूनी नज़रिए को विस्तार से सुनना अच्छा लगा
      मैं समझता हूँ कि लोग शिकायत करते हैं कि Rust पहले ही बड़ी भाषा है और वे नहीं चाहते कि यह और बड़ी हो, लेकिन मौजूदा आधी-पकी async implementation बनाए रखने से भाषा छोटी या सरल नहीं हो जाती। बस भाषा खराब हो जाती है। partial borrow भी public API नहीं, तो कम से कम उसी crate के अंदर ही काम करे तो अच्छा होगा। वास्तविक programming में यह समस्या लगातार सामने आती है। malicious crate sandboxing भाषा-स्तर पर असंभव क्यों है, यह भी मेरे लिए सवाल है। अगर call tree में unsafe third-party code नहीं है और function system calls भी नहीं करता, तो वह पहले से pass किए गए arguments, local variables और scope के अंदर के globals से ही deal कर सकता है। अगर इस दीवार को मजबूत करके security boundary की तरह इस्तेमाल किया जा सके, तो dependency supply chain risk काफी घटाया जा सकता है
  • Rust का mission शुरू से ही performance, safety और expressiveness को मिलाने वाला कठिन काम था, और Mozilla के हटने के बाद उसने founder mode खो दिया; original core team भी ज्यादातर जा चुकी है, इसलिए progress धीमी होना हैरानी की बात नहीं
    निजी तौर पर मुझे लगता है कि यह गलत रास्ते पर जाने से बेहतर है

  • अगर Rust को फिर से लिखा जाए, तो लगता है दिशा और features जोड़ने के बजाय घटाने की होगी
    जैसे QBE, LLVM के लिए करता है, वैसे code के 10% से Rust का 70% देना। macros और कुछ कम इस्तेमाल होने वाले features निकाल दें तो शायद संभव हो
    https://c9x.me/compile/

    • QBE को नीचा दिखाने का इरादा नहीं है, लेकिन QBE का शुरुआती लक्ष्य code के 10% से performance का 90% देना था, और बाद में यह 70% में बदल गया
      Rust हो या कुछ और, वास्तव में try करने से पहले यह जानना मुश्किल है कि कितना संभव है