1 पॉइंट द्वारा GN⁺ 6 일 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Ruby सोर्स को पूरे प्रोग्राम के type inference के बाद C code में बदलकर standalone native binary जनरेट करने वाला AOT compiler
  • Ruby के निर्माता matz द्वारा सीधे विकसित, और compiler backend खुद Ruby में लिखा गया है, इसलिए यह अपने आप को compile करने वाली self-hosting संरचना है
  • miniruby(Ruby 4.1.0dev) की तुलना में लगभग 11.6 गुना तेज प्रदर्शन, Conway's Game of Life में 86.7 गुना, ackermann में 74.8 गुना, mandelbrot में 58.1 गुना गति सुधार
  • Compile pipeline में Prism-आधारित parser पहले Ruby को AST text में बदलता है, फिर self-hosting backend type inference और C code generation करता है, और standard C compiler standalone binary बनाता है
  • class, inheritance, block, exception handling, Fiber, built-in NFA Regexp engine, automatic promotion Bigint, pattern matching जैसे Ruby के व्यापक फीचर सपोर्ट
  • 8 या उससे कम scalar field वाले छोटे class को value type के रूप में automatic stack allocation मिलता है, जिससे GC overhead पूरी तरह हट जाता है (10 लाख allocation 85ms → 2ms)
  • string chaining a + b + c + d को एक single malloc में flatten किया जाता है, और loop के अंदर split के लिए sp_StrArray को reuse करके अनावश्यक allocation हटाई जाती है
  • loop-invariant length hoisting, constant propagation, 3 स्टेटमेंट या उससे कम वाले method का automatic inline, repeated inference का early termination (~14% bootstrap time reduction) जैसी कई compile-time optimizations
  • जनरेट की गई binary में runtime dependency शून्य, और यह सिर्फ libc + libm के साथ चल सकती है
  • eval, metaprogramming, Thread और Mutex आदि सपोर्ट नहीं हैं (सिर्फ Fiber सपोर्ट है)
  • MIT लाइसेंस

1 टिप्पणियां

 
GN⁺ 6 일 전
Hacker News टिप्पणियाँ
  • अगर यह Matz ने बनाया है, तो उन्हें Ruby semantics की सीमाएँ भी अच्छी तरह पता होंगी, इसलिए इस पर भरोसा होता है
    मेरा मास्टर्स थीसिस भी AOT JS compiler पर था, और वह चलता तो था, लेकिन input data पर इतनी पाबंदियाँ थीं कि आखिरकार छोड़ना पड़ा
    उस समय JS developers खुद इस तरह की पाबंदियों का लगातार पालन करने के आदी नहीं थे, और JSON.parse जैसी मूल रूप से unknowable input बड़ी बाधा थी
    अब TypeScript की वजह से यह तब की तुलना में कहीं ज़्यादा व्यावहारिक हो सकता है
    सिर्फ सामान्य lambda calculus को देखें तो भी type inference की सीमाएँ साफ हैं, और Matt Might के papers या Shed-skin Python के काम में भी ऐसी ही पाबंदियाँ दिखती हैं
    मुझे जिज्ञासा है कि असली Ruby code में eval, send, method_missing, define_method कितने आम हैं, और बिना type वाली parsing, जैसे JSON input, आम तौर पर कैसे संभाली जाती है

    • यह डिज़ाइन काफ़ी pragmatic लगती है
      Ruby parsing, translation से भी ज़्यादा कठिन है, इसलिए इसमें Prism इस्तेमाल किया गया है, और output C generate होता है
      Ruby semantics का बेसिक हिस्सा अपने आप में इतना मुश्किल नहीं है
      दूसरी तरफ मैं एक पुराने self-hosting AOT compiler पर काम कर रहा हूँ जो pure Ruby में लिखा है, और उसने अपना parser बनाने की ज़िद करके जानबूझकर कहीं ज़्यादा कठिन रास्ता चुना
      शुरुआत के 80% में ही यह सीख लिया था कि मोटा-मोटी बनाकर भी काफ़ी Ruby code चलाया जा सकता है, और असल मुश्किल वाला "दूसरा 80%" उन चीज़ों में जमा है जिन्हें Matz ने इस प्रोजेक्ट और mruby से बाहर रखा है, जैसे encoding और तरह-तरह की peripheral सुविधाएँ
      ईमानदारी से कहूँ तो Ruby में कई ऐसी सुविधाएँ भी हैं जिन्हें मैंने असली code में कभी नहीं देखा, इसलिए कुछ अगर deprecated भी हो जाएँ तो मुझे अजीब नहीं लगेगा
      send, method_missing, define_method बहुत आम हैं
      पाबंदियाँ mruby जैसी हैं, और उन पाबंदियों के भीतर भी इसके उपयोग मौजूद हैं
      send, method_missing, define_method का support देना अपेक्षाकृत आसान है
      लेकिन eval() support करना बेहद दर्दनाक है
      फिर भी Ruby में eval() का बड़ा हिस्सा statically instance_eval के block version में घटाया जा सकता है, और ऐसे मामलों में AOT compilation काफ़ी आसान हो जाती है
      उदाहरण के लिए, अगर eval() में जाने वाली string को statically जाना या तोड़ा जा सके, तो समाधान की गुंजाइश बहुत बढ़ जाती है
      असल में eval() का बहुत-सा उपयोग अनावश्यक होता है या सिर्फ साधारण introspection workaround जैसा होता है, इसलिए static analysis से संभाला जा सकता है
      अगर मेरे compiler में वही bottleneck निकला, तो मैं वहीं से काम शुरू करूँगा
    • Rails-style magic बनाने के लिए ऐसी सुविधाएँ काफ़ी ज़रूरी होती हैं
      बिना type वाला JSON ingestion भी शायद इन्हीं mechanisms का इस्तेमाल करता होगा
      इन्हें हटाने पर Crystal जितना strongly typed नहीं, लेकिन आधिकारिक Ruby जितना metaprogramming-निर्भर भी नहीं, ऐसी एक छोटी और पढ़ने में आसान भाषा बचती है
      इसलिए इसमें काफ़ी potential दिखता है, लेकिन आखिरकार समय के साथ ही पता चलेगा
    • अगर Ruby को Objective-C में compile किया जाए, तो शायद Ruby की सारी सुविधाओं को support करते हुए भी interpreter Ruby से तेज़ बनाया जा सकता है
    • मैं eval का अक्सर इस्तेमाल करने वालों में हूँ
      इसके बिना काम चल सकता है, लेकिन मेरे लिए वह ज़्यादा ergonomic है
    • मेरे अनुभव में दिलचस्प चीज़ें eval, exec, define_method, और Class.new, Struct.new से नई classes बनाने वाले patterns हैं
      इनका ज़्यादातर उपयोग app boot के समय या files require करते समय होता है, और एक अर्थ में वह पहले से ही compilation stage जैसा है
  • यह वही है जिसे Matz ने अभी RubyKaigi 2026 में पेश किया
    यह experimental है, लेकिन Claude की मदद से लगभग एक महीने में बनाया गया, और live demo भी सफल रहा
    इसका नाम Matz की नई बिल्ली के नाम पर रखा गया है, और उस बिल्ली का नाम Card Captor Sakura की बिल्ली के नाम से आया है, जहाँ वह Ruby नाम वाले character के साथ जोड़ी बनाती है

    • लोग बहुत कहते हैं कि AI शुरू से अंत तक पूरा program बना देगा, लेकिन मुझे ज़्यादा यथार्थवादी scenario यह लगता है कि वह 10x programmer को 100x programmer बना दे
      Matz जैसे व्यक्ति के लिए यह शायद 100x को 500x तक धकेलने जैसा हो सकता है
    • मेरे दिमाग़ में Spinel का सबसे ताज़ा संदर्भ Steven Universe वाला था, इसलिए Spinel/Ruby (Moon) pun मुझे बिल्कुल समझ नहीं आया, लेकिन अब समझ आया तो दिन बन गया
    • मैंने तो स्वाभाविक रूप से mineral spinel ही सोचा था :)
      https://en.wikipedia.org/wiki/Spinel
    • धन्यवाद
      लगता है वीडियो अभी live नहीं है, और शायद इस चैनल पर एक-एक करके आ रहे हैं
      https://www.youtube.com/@rubykaigi4884/videos
    • बिल्ली के नाम की उत्पत्ति वाली बात, Ruby Central drama और Spinel.coop के founders के साथ रिश्तों को देखते हुए, काफ़ी संदिग्ध लगती है
      प्रोजेक्ट का नाम भी कुछ भावनात्मक तरीके से रखा हुआ लगता है
  • यह निस्संदेह बेहद प्रभावशाली है, लेकिन AI agent के बिना maintain करना असंभव-सा लगता है
    spinel_codegen.rb 21 हज़ार lines का है, और कुछ methods में 15 स्तर तक nesting है
    compiler code का सुंदर होना वैसे भी मुश्किल है, लेकिन यह उस मानक से भी इंसानों के लिए maintain करना बहुत कठिन लगता है

    • compiler code को समय हो तो काफ़ी सुंदर बनाया जा सकता है
      compilers में subsystem boundaries साफ़ होती हैं और stages के बीच handoff भी स्पष्ट होता है, इसलिए वे उल्टा सबसे modular बन सकने वाली चीज़ों में आते हैं
      समस्या आम तौर पर यह होती है कि पहले किसी तरह चला दिया जाता है और फिर refactor करने का समय नहीं मिलता, और तब गंदगी बढ़ती ही जाती है
    • spinel_codegen.rb तो लगभग eldritch horror स्तर का है
      Claude के साथ मेरे यहाँ भी हमेशा ऐसा ही spaghetti code निकलता है, तो मुझे लगा मैं ही कुछ ग़लत कर रहा हूँ
      लेकिन जिसे मैं top-tier programmer मानता हूँ, उसके इतने दिलचस्प प्रोजेक्ट में भी जगह-जगह code quality काफ़ी खराब दिखी, तो लगा समस्या सिर्फ मेरे साथ नहीं है
      उदाहरण के लिए infer_comparison_type() सबसे बुरा उदाहरण नहीं है, और पढ़ने में भी असंभव नहीं, लेकिन इसका कहीं ज़्यादा सरल और साफ़ implementation हो सकता था, फिर भी Claude वहाँ तक नहीं पहुँच पाया
      comparison operators को Set में रखकर include? से संभालें तो वह छोटा, तेज़, ज़्यादा readable और maintainable होगा
      लेकिन Claude हमेशा if-return chain की तरफ़ बह जाता है, और कभी-कभी तो लगता है जैसे if-else भी उसे अटपटा लगता है
      मेरे Claude codebase में भी ऐसे patterns भरे पड़े हैं, और अब समझ आया कि यह सिर्फ मेरे यहाँ नहीं है
      दूसरी तरफ़ बाकी files कहीं बेहतर हैं, खासकर lib directory, जो main Ruby repo की ext directory से मेल खाती लगती है और जिसकी quality ठीक है
      API पर MRI Ruby का असर साफ़ दिखता है, और भले implementation काफ़ी अलग हो, Matz ने output को ज़्यादा व्यवस्थित बनाने के लिए शायद original API के कुछ हिस्सों जैसा रखने को कहा होगा
      [1] https://github.com/matz/spinel/blob/98d1179670e4d6486bbd1547...
    • इस चरण पर यह इतना महत्वपूर्ण नहीं लगता कि इंसान इसे हाथ से maintain कर पाएँ या नहीं
      जब तक tests और benchmarks pass हो रहे हैं, मैं फ़िलहाल संतुष्ट हूँ
      लेकिन यह अलग सवाल है कि इतनी बड़ी file AI के लिए भी आसान है या नहीं
      मैं files को 300 lines के भीतर रखने की कोशिश करता हूँ, और मुझे लगता है कि जो code इंसानों के लिए समझना आसान है, वही coding agents के लिए भी आसान होगा
  • सीमाएँ ये बताई गई हैं
    No eval: eval, instance_eval, class_eval
    No metaprogramming: send, method_missing, define_method(dynamic)
    No threads: Thread, Mutex(Fiber supported)
    No encoding: UTF-8/ASCII मानकर चलता है
    No general lambda calculus: [] call के साथ गहरी nested -> x { }
    UTF-8/ASCII वाला हिस्सा मुझे व्यक्तिगत रूप से बहुत बड़ी सीमा नहीं लगता, लेकिन बाकी बातें काफ़ी programs में सचमुच बाधा बनेंगी
    और इन्हें वापस जोड़ने में भी काफ़ी काम लगता है

    • इससे Ruby का काफ़ी magic गायब हो जाता है
  • मैंने Ruby लंबे समय तक इस्तेमाल की है, और सूचीबद्ध सारी सुविधाएँ भी काम में ली हैं; उस नज़रिए से देखें तो विकास के बाद अब मुझे इसी तरह की सरल Ruby चाहिए
    यह ज़्यादा सरल और समझने योग्य है, फिर भी Ruby की खास aesthetic बची रहती है
    अब LLM की वजह से code generation productivity इतनी बढ़ गई है कि पहले जैसी metaprogramming से boilerplate घटाने की ज़रूरत कम हो गई है
    क्योंकि developers द्वारा खुद code लिखने का अनुपात ही घट रहा है

    • अगर आपको बस Ruby aesthetic चाहिए, तो Crystal भी आपको suit कर सकता है
      syntax मिलता-जुलता है और उसमें static type system है, जिससे ज़्यादा efficient compiled code मिलता है
    • eval का न होना तो शायद बेहतर ही है, लेकिन threads और mutexes का भी न होना खलता है
      define_method की अनुपस्थिति उसका उपयोग सोचकर समझ आती है
      लेकिन send और method_missing मौजूदा libraries में आम हैं, और implementation भी compile time पर memory lookup table बनाकर उतनी मुश्किल नहीं लगती
      इसलिए समझ नहीं आता कि इन्हें जानबूझकर छोड़ा गया है या बस अभी तक वहाँ पहुँचे नहीं हैं
      मेरी उम्मीद दूसरी बात है, लेकिन कम-से-कम अभी compatibility के कारण production use मुश्किल लगेगा
    • metaprogramming का असली फ़ायदा कम code लिखना नहीं था
      बल्कि कम code पढ़ना था
  • यह सच में शानदार है, और मैं लंबे समय से Ruby के लिए AOT compiler का इंतज़ार कर रहा था
    बस eval या metaprogramming fallback का न होना अफ़सोस की बात है, हालांकि लगता है कि ऐसा छोटे high-performance subset पर ध्यान केंद्रित करने के लिए किया गया है
    अच्छा होगा अगर इस AOT compiler से बने gem, MRI के साथ अच्छी तरह interact करें
    standard Ruby और gems को package या bundle करने के लिए अभी भी tebako, kompo, ocran की ज़रूरत रहती है, और पहले ruby-packer, traveling ruby, jruby warbler जैसे projects भी थे
    एक और विकल्प आना अच्छी बात है, लेकिन मैं बेहतर developer UX वाले अंतिम निर्णायक समाधान का इंतज़ार कर रहा हूँ

    • सही बात, मुझे भी हाल ही में warbler fork करना पड़ा
      क्योंकि बहुत लंबे समय से उसका update नहीं आया था
  • मुझे समझ नहीं आता no threads क्यों
    Ruby scheduler और नीचे का pthread implementation तो C layer में भी ठीक से काम करना चाहिए, इसलिए लगा शायद zero dependency की कोशिश होगी
    अगर optional extension के रूप में बाद में जोड़ने की योजना नहीं है, या यह सिर्फ अभी तक नहीं हुआ, तो यह चुनाव थोड़ा अजीब लगता है

    • मैंने अभी तक ऐसा कोई संकेत नहीं देखा कि इसे जानबूझकर support न करने का फ़ैसला लिया गया है
      शायद बस अभी तक वहाँ पहुँचे नहीं हैं
      multithreading को ठीक से बनाना वैसे भी बहुत कठिन होता है
  • यह जानकर हैरानी हुई कि इसे एक महीने से थोड़ा ज़्यादा समय में बना लिया गया
    AI के बारे में कुछ भी कहें, कुशल developers के हाथ में यह गति में ज़बरदस्त बढ़ोतरी लाता है

    • पूरी industry agent harness, SOUL.md, permission settings, skills, MCPs, hooks, env वगैरह सब लगाकर शुरू करती है
      और Matz बस gem env|info और find से काम चला लेते हैं, ऐसा लगता है
  • चूँकि इसे Matz ने बनाया है, इसलिए यह जानना दिलचस्प है कि भविष्य में इसके Ruby core का हिस्सा बनने की कितनी वास्तविक संभावना है
    और अगर ऐसा हुआ तो Crystal के लिए यह कितना ख़तरा होगा

    • Crystal में स्पष्ट static type system है, और भाषा स्तर पर ही AOT compilation के लिए optimize किया गया है
      बड़े programs को compile और maintain करने के लिए ये विशेषताएँ लगभग अनिवार्य जैसी हैं
      दूसरी ओर यह सीमित Ruby subset के लिए है, इसलिए ज़्यादातर लोकप्रिय Ruby gems इसमें वैसे के वैसे नहीं चलेंगे
      C compilation की ओर उन्मुख language subset होने के लिहाज़ से यह PreScheme के ज़्यादा करीब लगता है
      अभी के चरण में मुझे नहीं लगता कि दोनों सीधे एक ही क्षेत्र में प्रतिस्पर्धा कर रहे हैं
      पूरी Ruby के लिए लगभग निश्चित रूप से JIT चाहिए होगा
      [1]: https://prescheme.org/
    • दूसरे नज़रिए से देखें तो आख़िरकार LLM उस बिंदु तक पहुँच जाएँगे जहाँ वे हमारी मनचाही किसी भी भाषा में formal specification उगल सकेंगे
      यह कुछ-कुछ Rational Unified Process और Enterprise Architect जैसे tools की वापसी जैसा होगा
      फ़र्क बस इतना होगा कि UML diagrams की जगह markdown files आएँगी
  • यह infrastructure tools के क्षेत्र में उपयोगी हो सकता है
    मान लीजिए bundler Ruby में लिखा है लेकिन statically compiled है, और साथ में RVM जैसे Ruby installation tool की भूमिका भी निभा लेता है
    मौजूदा Ruby buildpack Ruby में लिखा होने के बावजूद bootstrap के लिए bash की ज़रूरत रखता है, जो परेशान करता है और edge cases भी पैदा करता है
    CNB ने उस समस्या से बचने के लिए Rust चुना, और बिना dependencies वाला single binary वितरित कर पाना सचमुच बहुत शक्तिशाली विचार है