अगर Rust को फिर से लिखा जाए
(josephg.com)- 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 के लंबे समय तक अटके रहने की जगह जैसा दिखता है
Muteximprovement 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
unsafecode 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 में जैसे
unsafeexplicit 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_writecapability चाहिए, तो caller कोCargo.tomlया call-site annotation के जरिए explicit रूप से allow करना होगा - allow न करने पर compiler error दे सकता है कि
foo::do_stuff()local file system पर write करता है, लेकिनfoocrate को उस capability के लिए trusted नहीं माना गया human-sizeयाserdeजैसी कई utility crates को special capability की जरूरत नहीं होती, इसलिए author malicious code जोड़ भी दे तो file write या network activity को compile stage पर रोका जा सकता है- विकल्प के रूप में sensitive API को अलग
Capabilityparameter लेने के लिए बदलने का तरीका भी है- उदाहरण:
std::fs::writeकोFsWriteCapabilityvalue चाहिए Capabilityobject बनाना केवल root crate में संभव होने तक सीमित किया जाए
- उदाहरण:
- इस तरीके में boilerplate बढ़ेगा, लेकिन यह ज्यादा flexible है, और
build.rsscripts तथाunsafeblocks पर भी समान 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 करने वाले
Movemarker trait जैसी चीज़ की है - मौजूदा Rust में
Pintrait नहीं है, बल्किUnpinऔर!Unpinहैं, और double negative form concept को और कठिन बना देता है - आलोचना है कि
Pinकेवल reference types पर apply होता है, इसलिए जगह-जगहBoxमें wrap करने वाला code बनता है- उदाहरण के तौर पर Tokio stream wrapper,
ouroboros,async-trait,self_cellजैसी helper libraries linked हैं
- उदाहरण के तौर पर Tokio stream wrapper,
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 को पता होगा कि
xborrowed है और function के अंदर borrowed variable जैसी constraints लागू करेगा
- उदाहरण:
- ऐसी syntax self-referential struct या AST में
source: Stringऔरast_nodes: Vec<&'Self::source str>जैसे forms handle करने में भी इस्तेमाल हो सकती है - borrowed field वाली struct movable नहीं होगी, इसलिए वह
Moveimplement नहीं करेगी, और आगे चलकर खुद को safely move करने वालाMovertrait भी 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 printcase study format string को comptime parameter के रूप में लेकर,comptimeloop में parse कर output code generate करने का example है - Rust का
println!()implementationformat_args_nlजैसी internal function call करता है, और अनुमान है कि यह function compiler में hardcoded है - इसके बाद आलोचना आती है कि Rust compiler authors भी Rust macro language इस्तेमाल नहीं करना चाहते लगते हैं
syntax और standard library में छोटे fixes
Range<T>काT: Copyहोने परCopyimplement करने वाला issue fix करना चाहने की बात है- associated type वाले derive issue को भी fix target माना गया है
- related issue: derive with associated types
- example: Playground
- proposal है कि
if letexpressions को 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
- desired form:
- raw pointer ergonomics को भी improvement target माना गया है
- references में
myref.xलिखा जा सकता है, लेकिन pointer में(*myptr).xया(*(*myptr).p).yजैसा लिखना पड़ता है - stance है कि
unsafecode जितना हो सके पढ़ने-लिखने में आसान होना चाहिए
- references में
- 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 टिप्पणियां
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 रहेउदाहरण के लिए,
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 बेहतर हैभले ही queue में पड़े ideas 100% accept होकर आखिरकार उन पर काम हो जाए, incoming और outgoing गति के फर्क की वजह से वह ऐसा ही दिखता है। अगर आप RFC authors से आगे निकलना चाहते हैं, तो RFC न लिखें; documentation और tests के साथ production-ready implementation बनाएं, जिसे tree में साफ-सुथरे तरीके से merge किया जा सके
उन्हें न तो दूसरे type के const generic के रूप में, न ही array length के रूप में इस्तेमाल कर सकते हैं। अगर बस value चाहिए, तो function define करके return कर सकते हैं, इसलिए फिलहाल यह ज्यादा उपयोगी नहीं है। सही support मिल जाए तो cryptography libraries में
generic_array,typenumजैसे helper crates हटाए जा सकते हैं। फिर भी मैं सहमत हूँ कि Rust team को features जोड़ने में सावधान रहना चाहिएनिर्भरता की स्थिति काफ़ी गंभीर है, लेकिन लगता है कि इसे मानने वाले लोग बहुत कम हैं। हाल में देखा गया उदाहरण 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
C/C++ व्यापक रूप से इस्तेमाल होने वाली भाषाओं में लगभग अकेला उदाहरण है जहाँ npm-शैली का package manager लोकप्रिय नहीं है, इसलिए ज़्यादातर libraries self-contained होती हैं या उनकी dependencies कम और अक्सर optional होती हैं।
efswबिना dependency वाला 7,000-line का C++ file system watcher है। game programming की single-header librariesstb_*,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
file watcher, ख़ासकर जब कई platforms support करने हों, मुझे तो बिल्कुल भी सरल नहीं लगता
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 कुल मिलाकर उसी तरफ़ ज़्यादा हैcargo-watchकी अधिकांश dependencies शायद तीन direct requirementsclap,cargo_metadata,watchexecसे आती हैं।clapplatform-specific CLI elements बहुत खींच लाता है, औरcargo_metadataकोserdefamily की बहुत सारी चीज़ें लानी ही पड़ती हैं।watchexecमें सुधार की गुंजाइश है; यह उसी संगठन द्वारा maintain किए जाने वालेcommand-groupपर निर्भर है, और वह बिना शर्त Tokio मांगता है। बड़ा मुद्दा यह है कि दूसरे crates की अत्यधिक dependencies को आसानी से ठीक नहीं किया जा सकता। अगर कोई crate पुरानेwatchexecसे बंधा है, तो कभी-कभीCargo.lockadjust करके काम चल सकता है, लेकिन आम तौर पर मुश्किल होता है और[patch]से workaround करना पड़ता है। किसी खास version के crate को बदलने के लिए “stand-in” आसानी से define करने का तरीका हो तो अच्छा होगा, लेकिन मौजूदा package managers के लिए यह बड़ा research problem लगता हैRust अब कोई रोमांचक नई भाषा नहीं रही; यह व्यापक adoption की ओर बढ़ने वाला चरण है। feature development का धीमा होना स्वाभाविक और स्वस्थ है
इस समय design mistakes, धीमी गति से कहीं ज़्यादा नुकसानदेह हैं। Rust इसलिए दिलचस्प नहीं है कि उसमें शानदार features हैं, बल्कि इसलिए कि यह memory-safe, garbage collection के बिना, production-ready भाषाओं की एक नई श्रेणी है। महत्वपूर्ण जगहों पर इसका वास्तविक adoption, भाषा को और बेहतर बनाने से ज़्यादा दिलचस्प है, और सावधानी से संचालन होने का भरोसा हो तो यह आसान होता है
spread operator, generator functions,
async, arrow functions,leftpad, नयाDate—महत्वपूर्ण features की सूची खत्म ही नहीं होती। JS, Rust से कहीं पुरानी और कहीं ज़्यादा व्यापक रूप से इस्तेमाल होने वाली भाषा है, और इसके कई production implementations हैं, इसलिए सभी नए features को मिलाकर implement करना पड़ता है। ES5 के आसपास ठहराव का दौर था, लेकिन फर्क शायद इस बात में दिखता है कि ECMAScript standards committee ने खुद को संभाल लियाRustaceans हर चीज़ को Rust में दोबारा लिखने को लेकर इतने obsessed हैं कि सच में लगा था कि Rust को दोबारा लिखने वाला लेख कोई meta-satire joke होगा
पहले धीले 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 मिले
Rust हर संभव feature जोड़ने की कोशिश नहीं कर रहा। बस GAT या TAIT जैसी चीज़ें अगर यह साफ़ जाने बिना दिखें कि वे कौन-सी समस्या हल करती हैं, तो ऐसा लग सकता है। Zig एक अच्छी modern language हो सकती है, लेकिन अगर लक्ष्य memory safety है तो वह विकल्प नहीं है
उदाहरण के लिए
Pinऔर futures का interaction language में बेतुकी complexity जोड़ता है, और मुझे लगता है कि उसका कुछ हिस्सा अनावश्यक है। काश Rust जैसी कोई language होती जिसमेंPinबिल्कुल न होता। borrow checker को भी syntax और implementation दोनों तरफ से simplify करने के तरीके हो सकते हैं, हालांकि मैंने अभी उस पर ठोस रूप से नहीं सोचा है। फिलहाल language को fork किए बिना इसे बदलना मुश्किल होगा, लेकिन borrow checker इस्तेमाल करने वाली language के रूप में Rust आख़िरी नहीं होगी। उम्मीद है कि अगली generation में और बड़ी language बनाए बिना भी सुधार की काफी गुंजाइश होगीRust से जुड़े dramas दिखते हैं, लेकिन आम तौर पर वे Rust के इस्तेमाल या adoption का विरोध करने वालों की तरफ से पैदा होते हैं। जैसे हाल का Rust for Linux हंगामा। community के अंदर यह आम बात नहीं लगती, हालांकि हो सकता है मैंने कुछ miss किया हो। Zig शानदार है, लेकिन अभी production ready नहीं है
लिंक किए गए 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काimpledition के जरिए 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 होने की संभावना कम है उन्हें साफ़ करने के लिए बड़ा काम चाहिएज़्यादा declarative macros,
-syscrate 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
मैं समझता हूँ कि लोग शिकायत करते हैं कि Rust पहले ही बड़ी भाषा है और वे नहीं चाहते कि यह और बड़ी हो, लेकिन मौजूदा आधी-पकी async implementation बनाए रखने से भाषा छोटी या सरल नहीं हो जाती। बस भाषा खराब हो जाती है। partial borrow भी public API नहीं, तो कम से कम उसी crate के अंदर ही काम करे तो अच्छा होगा। वास्तविक programming में यह समस्या लगातार सामने आती है। malicious crate sandboxing भाषा-स्तर पर असंभव क्यों है, यह भी मेरे लिए सवाल है। अगर call tree में
unsafethird-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/
Rust हो या कुछ और, वास्तव में try करने से पहले यह जानना मुश्किल है कि कितना संभव है