Spinel: Ruby AOT नेटिव कंपाइलर
(github.com/matz)- Ruby कोड को standalone native binary में बदलता है, और पूरे प्रोग्राम-स्तर की type inference व C code generation के जरिए नवीनतम CRuby
minirubyकी तुलना में geometric mean पर लगभग 11.6x तेज़ execution का लक्ष्य रखता है - कंपाइल पाइपलाइन Prism-आधारित parser से Ruby को AST text में बदलने के बाद self-hosting backend के जरिए type inference और C code generation करती है, फिर standard C compiler से standalone binary बनाती है
- compiler backend Ruby में लिखा गया self-hosting architecture रखता है, और bootstrap प्रक्रिया के बाद
gen2.c == gen3.cस्थापित होता है, जिससे अपने-आप को फिर से compile करने वाला loop बंद हो जाता है - string concat flattening, value-type promotion, loop-invariant length hoisting, static symbol interning, bigint auto-promotion जैसे compile-time optimization शामिल हैं, और built-in regexp engine, bigint, तथा single-header runtime के जरिए बाहरी runtime dependency कम की जाती है
eval, metaprogramming, Thread, और सामान्य encoding handling समर्थित नहीं हैं, लेकिन Ruby के बिना चलने वाले deployment form और compute-intensive workload में बड़े performance अंतर Ruby AOT compilation की व्यावहारिकता दिखाते हैं
यह कैसे काम करता है
- कंपाइल पाइपलाइन Ruby file को parse करके AST text file में serialize करती है, फिर type inference और C code generation के बाद standard C compiler से native binary बनाती है
spinel_parsePrism और libprism का उपयोग करके Ruby को parse करता है, और जब C binary उपलब्ध न हो तो CRuby और Prism gem का उपयोग करने वाला fallback path अपनाता हैspinel_codegenself-hosted native binary के रूप में चलता है, AST लेकर type inference + C code generation करता है- अंतिम चरण
cc -O2 -Ilib -lmके साथ C source और runtime header को compile करता है, और परिणामस्वरूप binary standalone रूप में बनती है
Self-Hosting
- bootstrap chain
CRuby + spinel_parse.rbसे AST बनाती है,CRuby + spinel_codegen.rbसेgen1.cऔरbin1बनाती है, और फिर बने हुए binary सेgen2.c,gen3.cबनाकर loop बंद करती है gen2.c == gen3.cयह स्पष्ट करता है कि bootstrap loop बंद हो चुका है- backend
spinel_codegen.rbSpinel द्वारा सीधे compile किए जा सकने वाले Ruby subset में लिखा गया है- classes,
def,attr_accessor if/case/whileeach/map/select,yieldbegin/rescue- String, Array, Hash operations और File I/O
- classes,
- backend में metaprogramming,
eval,requireशामिल नहीं हैं
प्रदर्शन और बेंचमार्क
- टेस्ट में 74 पास, बेंचमार्क में 55 पास की स्थिति है
- 28 benchmarks के आधार पर geometric mean नवीनतम CRuby
minirubyकी तुलना में लगभग 11.6x तेज़ है - तुलना का आधार bundled gem के बिना बना नवीनतम CRuby
minirubybuild है, और systemruby3.2.3 से भी तेज़ baseline के मुकाबले compute-intensive workload में बढ़त बड़ी है -
computation performance
life20ms बनाम 1,733ms, यानी 86.7x तेज़ackermann5ms बनाम 374ms, यानी 74.8x तेज़mandelbrot25ms बनाम 1,453ms, यानी 58.1x तेज़- recursive
fibversion 17ms बनाम 581ms, यानी 34.2x तेज़ nqueens10ms बनाम 304ms, यानी 30.4x तेज़tarai16ms बनाम 461ms, यानी 28.8x तेज़tak22ms बनाम 532ms, यानी 24.2x तेज़matmul13ms बनाम 313ms, यानी 24.1x तेज़sudoku6ms बनाम 102ms, यानी 17.0x तेज़partial_sums93ms बनाम 1,498ms, यानी 16.1x तेज़fannkuch2ms बनाम 19ms, यानी 9.5x तेज़sieve39ms बनाम 332ms, यानी 8.5x तेज़fasta3ms बनाम 21ms, यानी 7.0x तेज़
-
data structures और GC
rbtree24ms बनाम 543ms, यानी 22.6x तेज़splay tree14ms बनाम 195ms, यानी 13.9x तेज़huffman6ms बनाम 59ms, यानी 9.8x तेज़so_lists76ms बनाम 410ms, यानी 5.4x तेज़binary_trees11ms बनाम 40ms, यानी 3.6x तेज़linked_list136ms बनाम 388ms, यानी 2.9x तेज़gcbench1,845ms बनाम 3,641ms, यानी 2.0x तेज़
-
वास्तविक प्रोग्राम
json_parse39ms बनाम 394ms, यानी 10.1x तेज़bigint_fibमें 1000-digit calculation 2ms बनाम 16ms, यानी 8.0x तेज़ao_render417ms बनाम 3,334ms, यानी 8.0x तेज़pidigits2ms बनाम 13ms, यानी 6.5x तेज़str_concat2ms बनाम 13ms, यानी 6.5x तेज़template engine152ms बनाम 936ms, यानी 6.2x तेज़csv_process234ms बनाम 860ms, यानी 3.7x तेज़io_wordcount33ms बनाम 97ms, यानी 2.9x तेज़
समर्थित Ruby फीचर
- Core फीचर के रूप में classes, inheritance,
super,includemixin,attr_accessor,Struct.new,alias, module constants, और built-in types के लिए open classes समर्थित हैं - Control Flow में
if/elsif/else,unless,case/when,case/inpattern matching,while,until,loop,for..in,break,next,return,catch/throw,&.समर्थित हैं - Blocks में
yield,block_given?,&block,proc {},Proc.new,-> x { },method(:name)समर्थित हैं, औरeach,map,select,reduce,sort_by,times,upto,downtoजैसे block methods भी शामिल हैं - Exceptions में
begin/rescue/ensure/retry,raise, और user-defined exception classes समर्थित हैं - Types में Integer, Float, String, Array, Hash, Range, Time, StringIO, File, Regexp, Bigint, Fiber शामिल हैं
- polymorphic values को tagged unions के रूप में संभाला जाता है
- self-referential data structures के लिए nullable object types
T?दिए गए हैं
- Global Variables में
$nameको static C variables के रूप में compile किया जाता है, और type mismatch compile time पर पकड़ा जाता है - I/O में
puts,print,printf,p,gets,ARGV,ENV[],File.read/write/open,system(), backticks समर्थित हैं
string, regexp, symbol, Bigint, Fiber
- Strings immutable और mutable strings दोनों को संभालते हैं, और
<<अपने-आप mutable stringsp_Stringमें promote होकर O(n) in-place append करता है +, interpolation,tr,ljust/rjust/centerऔर standard methods दोनों string representations पर काम करते हैंs[i] == "c"जैसी तुलना सीधे char array access के लिए optimize की जाती है, इसलिए बिना allocation के काम होता हैa + b + c + dजैसे concat को एक बार केsp_str_concat4याsp_str_concat_arrcall में flatten किया जाता है, जिससे N-1 कम allocation होते हैं- loop के अंदर
str.split(sep)उसीsp_StrArrayको बार-बार reuse करता है, औरcsv_processमें 40 लाख allocations हट जाते हैं - Regexp बाहरी dependency के बिना built-in NFA regexp engine का उपयोग करता है
=~,$1-$9,match?,gsub,sub,scan,splitसमर्थित हैं
- Bigint mruby-bigint आधारित arbitrary-precision integers का उपयोग करता है
q = q * kजैसे loop multiplication patterns में auto-promotion होता है- static library के रूप में link होता है और केवल वास्तविक उपयोग पर शामिल किया जाता है
- Fiber
ucontext_tआधारित cooperative concurrency देता हैFiber.new,Fiber#resume,Fiber.yieldऔर value passing समर्थित हैं- free variables को heap-promoted cells के रूप में capture किया जाता है
- Symbols string से अलग
sp_symtype के रूप में implemented हैं:a != "a"बना रहता है- symbol literals compile time पर intern होकर
SPS_nameconstants बनते हैं String#to_symकेवल ज़रूरत पड़ने पर dynamic pool का उपयोग करता है- symbol-key hash
sp_SymIntHashका उपयोग करता है, जो string की जगह integer keys सीधे store करता है, इसलिए strcmp और dynamic string allocation समाप्त हो जाते हैं
memory management और value types
- memory management में mark-and-sweep GC का उपयोग होता है, जिसमें size-segregated free lists, non-recursive marking, sticky mark bits शामिल हैं
- छोटे और सरल classes को अपने-आप value types में promote कर stack पर रखा जाता है
- शर्तें: 8 या उससे कम scalar fields
- inheritance नहीं
- parameters के ज़रिए mutation नहीं
- 5-field class की 10 लाख allocations 85ms से घटकर 2ms हो जाती हैं
- केवल value types इस्तेमाल करने वाले प्रोग्राम GC runtime को बिल्कुल export नहीं करते
optimization
- पूरे प्रोग्राम-स्तर की type inference के आधार पर कई compile-time optimization किए जाते हैं
- Value-type promotion के जरिए छोटे immutable classes C struct stack objects बन जाते हैं, जिससे GC overhead हट जाता है
- Constant propagation में
N = 100जैसे simple literal constantscst_Nlookup के बिना सीधे use site पर inline हो जाते हैं - Loop-invariant length hoisting में
while i < arr.lengthके लिए length loop से पहले केवल एक बार निकाली जाती है- अगर body में
arr.pushकी तरह receiver object बदलता है, तो यह hoist निष्क्रिय हो जाता है
- अगर body में
- Method inlining छोटे, non-recursive, 3 statements तक वाले methods पर
static inlineलगाकर gcc inlining को प्रोत्साहित करता है - String concat chain flattening concat chain को single call में बदलकर intermediate string creation हटाता है
- Bigint auto-promotion self-referential addition या repeated multiplication patterns को अपने-आप bigint में promote करता है
- Bigint
to_smruby-bigint केmpz_get_strका उपयोग करके divide-and-conquer O(n log²n) में चलता है - Static symbol interning
"literal".to_symको compile-timeSPS_<name>constant में बदलता है, और dynamic interning होने पर ही runtime pool जोड़ता है sub_rangeमें length-hoisted stringsp_str_sub_range_lenका उपयोग करती है, जिससे अंदरूनीstrlencall छूट जाता है- loop के अंदर
line.split(",")मौजूदाsp_StrArrayको reuse करता है - Dead-code elimination
-ffunction-sections -fdata-sectionsऔर--gc-sectionsके जरिए इस्तेमाल न होने वाले runtime functions को final binary से हटा देता है - Iterative inference early exit में param, return, ivar के 3 signature arrays में बदलाव रुकते ही fixed-point loop तुरंत रोक दिया जाता है
- अधिकांश प्रोग्राम 4 full iterations की जगह 1–2 iterations में converge करते हैं
- bootstrap time लगभग 14% कम हो जाता है
parse_id_listbyte walk self-compile के दौरान लगभग 1.2 लाख बार बुलाए जाने वाले AST field list parser मेंs.split(",")की जगहs.bytes[i]manual traversal उपयोग करता है, जिससे प्रति call allocation N+1 से घटकर 2 रह जाती है- generated C code default warning level पर warning-free build बनाए रखता है, और harness
-Werrorका उपयोग करके regression तुरंत सामने लाता है
architecture
- repository structure निम्न हिस्सों में बंटी है
spinel: POSIX shell आधारित one-command wrapper scriptspinel_parse.c: libprism से text AST तक जाने वाला C frontend, 1,061 linesspinel_codegen.rb: AST से C code तक जाने वाला compiler backend, 21,109 lineslib/sp_runtime.h: runtime library header, 581 lineslib/sp_bigint.c: arbitrary-precision integer, 5,394 lineslib/regexp/: built-in regexp engine, 1,759 linestest/: 74 functional testsbenchmark/: 55 benchmarksMakefile: build automation
- runtime
lib/sp_runtime.hGC, array/hash/string implementation और अन्य runtime support को एक header file में रखता है - generated C code इस header को include करता है, और linker
libspinel_rt.aसे केवल ज़रूरी हिस्से लाता है- bigint
- regexp engine
- parser के दो implementations हैं
spinel_parse.clibprism को सीधे link करके CRuby के बिना चलता हैspinel_parse.rbPrism gem का उपयोग करने वाला CRuby fallback है
- दोनों parser समान AST output बनाते हैं, और
spinelwrapper संभव हो तो C binary को प्राथमिकता देता है require_relativeparsing stage पर resolve होकर referenced files inline कर दिए जाते हैं
सीमाएँ
- No eval:
eval,instance_eval,class_evalसमर्थित नहीं हैं - No metaprogramming:
send,method_missing, dynamicdefine_methodसमर्थित नहीं हैं - No threads:
Thread,Mutexसमर्थित नहीं; केवल Fiber समर्थित है - No encoding: UTF-8 और ASCII मानकर चलता है
- No general lambda calculus: गहराई से nested
-> x { }और[]calls को handle नहीं करता
dependencies और execution model
- build-time dependencies में libprism C library और शुरुआती bootstrap के लिए CRuby शामिल हैं
- runtime dependency नहीं है, और generated binary को केवल libc + libm चाहिए
- regexp built-in engine का उपयोग करता है, इसलिए बाहरी library की ज़रूरत नहीं होती
- Bigint built-in है, लेकिन केवल वास्तविक उपयोग पर link होता है
- Prism वह Ruby parser है जिसका उपयोग
spinel_parseकरता हैmake depsrubygems.org से prism gem tarball डाउनलोड करके C source कोvendor/prismमें extract करता है- अगर prism gem पहले से installed हो तो इसे अपने-आप detect कर लिया जाता है
PRISM_DIR=/path/to/prismके जरिए custom path भी दिया जा सकता है
- CRuby केवल शुरुआती bootstrap के लिए चाहिए;
makeके बाद पूरी पाइपलाइन Ruby के बिना चलती है
प्रोजेक्ट इतिहास
- Spinel शुरू में C में implement किया गया था, इसका आकार 18K lines था, और यह
c-versionbranch में मौजूद है - इसके बाद Ruby में दोबारा लिखा गया
ruby-v1branch आया - वर्तमान
masterself-hosting सक्षम Ruby subset में दोबारा लिखे गए version का प्रतिनिधित्व करता है
लाइसेंस
- MIT License का उपयोग किया जाता है
- LICENSE file का पालन करता है
1 टिप्पणियां
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, आम तौर पर कैसे संभाली जाती है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 निकला, तो मैं वहीं से काम शुरू करूँगा
बिना type वाला JSON ingestion भी शायद इन्हीं mechanisms का इस्तेमाल करता होगा
इन्हें हटाने पर Crystal जितना strongly typed नहीं, लेकिन आधिकारिक Ruby जितना metaprogramming-निर्भर भी नहीं, ऐसी एक छोटी और पढ़ने में आसान भाषा बचती है
इसलिए इसमें काफ़ी potential दिखता है, लेकिन आखिरकार समय के साथ ही पता चलेगा
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 के साथ जोड़ी बनाती है
Matz जैसे व्यक्ति के लिए यह शायद 100x को 500x तक धकेलने जैसा हो सकता है
https://en.wikipedia.org/wiki/Spinel
लगता है वीडियो अभी live नहीं है, और शायद इस चैनल पर एक-एक करके आ रहे हैं
https://www.youtube.com/@rubykaigi4884/videos
प्रोजेक्ट का नाम भी कुछ भावनात्मक तरीके से रखा हुआ लगता है
यह निस्संदेह बेहद प्रभावशाली है, लेकिन AI agent के बिना maintain करना असंभव-सा लगता है
spinel_codegen.rb21 हज़ार lines का है, और कुछ methods में 15 स्तर तक nesting हैcompiler code का सुंदर होना वैसे भी मुश्किल है, लेकिन यह उस मानक से भी इंसानों के लिए maintain करना बहुत कठिन लगता है
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 कहीं बेहतर हैं, खासकर
libdirectory, जो main Ruby repo कीextdirectory से मेल खाती लगती है और जिसकी quality ठीक हैAPI पर MRI Ruby का असर साफ़ दिखता है, और भले implementation काफ़ी अलग हो, Matz ने output को ज़्यादा व्यवस्थित बनाने के लिए शायद original API के कुछ हिस्सों जैसा रखने को कहा होगा
[1] https://github.com/matz/spinel/blob/98d1179670e4d6486bbd1547...
जब तक tests और benchmarks pass हो रहे हैं, मैं फ़िलहाल संतुष्ट हूँ
लेकिन यह अलग सवाल है कि इतनी बड़ी file AI के लिए भी आसान है या नहीं
मैं files को 300 lines के भीतर रखने की कोशिश करता हूँ, और मुझे लगता है कि जो code इंसानों के लिए समझना आसान है, वही coding agents के लिए भी आसान होगा
सीमाएँ ये बताई गई हैं
No eval:
eval,instance_eval,class_evalNo 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 लंबे समय तक इस्तेमाल की है, और सूचीबद्ध सारी सुविधाएँ भी काम में ली हैं; उस नज़रिए से देखें तो विकास के बाद अब मुझे इसी तरह की सरल Ruby चाहिए
यह ज़्यादा सरल और समझने योग्य है, फिर भी Ruby की खास aesthetic बची रहती है
अब LLM की वजह से code generation productivity इतनी बढ़ गई है कि पहले जैसी metaprogramming से boilerplate घटाने की ज़रूरत कम हो गई है
क्योंकि developers द्वारा खुद code लिखने का अनुपात ही घट रहा है
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 मुश्किल लगेगा
बल्कि कम 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 वाले अंतिम निर्णायक समाधान का इंतज़ार कर रहा हूँ
क्योंकि बहुत लंबे समय से उसका update नहीं आया था
मुझे समझ नहीं आता no threads क्यों
Ruby scheduler और नीचे का pthread implementation तो C layer में भी ठीक से काम करना चाहिए, इसलिए लगा शायद zero dependency की कोशिश होगी
अगर optional extension के रूप में बाद में जोड़ने की योजना नहीं है, या यह सिर्फ अभी तक नहीं हुआ, तो यह चुनाव थोड़ा अजीब लगता है
शायद बस अभी तक वहाँ पहुँचे नहीं हैं
multithreading को ठीक से बनाना वैसे भी बहुत कठिन होता है
यह जानकर हैरानी हुई कि इसे एक महीने से थोड़ा ज़्यादा समय में बना लिया गया
AI के बारे में कुछ भी कहें, कुशल developers के हाथ में यह गति में ज़बरदस्त बढ़ोतरी लाता है
और Matz बस
gem env|infoऔरfindसे काम चला लेते हैं, ऐसा लगता हैचूँकि इसे Matz ने बनाया है, इसलिए यह जानना दिलचस्प है कि भविष्य में इसके Ruby core का हिस्सा बनने की कितनी वास्तविक संभावना है
और अगर ऐसा हुआ तो Crystal के लिए यह कितना ख़तरा होगा
बड़े programs को compile और maintain करने के लिए ये विशेषताएँ लगभग अनिवार्य जैसी हैं
दूसरी ओर यह सीमित Ruby subset के लिए है, इसलिए ज़्यादातर लोकप्रिय Ruby gems इसमें वैसे के वैसे नहीं चलेंगे
C compilation की ओर उन्मुख language subset होने के लिहाज़ से यह PreScheme के ज़्यादा करीब लगता है
अभी के चरण में मुझे नहीं लगता कि दोनों सीधे एक ही क्षेत्र में प्रतिस्पर्धा कर रहे हैं
पूरी Ruby के लिए लगभग निश्चित रूप से JIT चाहिए होगा
[1]: https://prescheme.org/
यह कुछ-कुछ 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 वितरित कर पाना सचमुच बहुत शक्तिशाली विचार है