Spinel - Ruby AOT yerel derleyicisi
(github.com/matz)- Ruby kaynak kodunu tüm program tür çıkarımı sonrasında C koduna dönüştürerek bağımsız çalışan yerel ikililer üreten bir AOT derleyicisi
- Ruby'nin yaratıcısı matz tarafından doğrudan geliştiriliyor; derleyici backend'inin kendisi de Ruby ile yazılmış ve kendisini derleyen self-hosting bir yapıya sahip
- miniruby'ye (Ruby 4.1.0dev) kıyasla yaklaşık 11,6 kat daha yüksek performans; Conway's Game of Life 86,7 kat, ackermann 74,8 kat, mandelbrot ise 58,1 kat hızlanıyor
- Derleme hattı, Prism tabanlı ayrıştırıcıyla Ruby'yi AST metnine dönüştürdükten sonra self-hosting backend tür çıkarımı ve C kod üretimini yapıyor; ardından standart bir C derleyicisiyle standalone ikili oluşturuluyor
- Sınıflar, kalıtım, bloklar, istisna işleme, Fiber, yerleşik NFA tabanlı Regexp motoru, otomatik terfi eden Bigint, pattern matching gibi geniş bir Ruby özellik kümesini destekliyor
- 8 veya daha az skaler alana sahip küçük sınıflar, değer tipi olarak otomatik stack tahsisi ile yerleştiriliyor; böylece GC ek yükü tamamen ortadan kalkıyor (1 milyon tahsis 85 ms → 2 ms)
- Dize zincirleme
a + b + c + d, tek bir malloc ile düzleştiriliyor; döngü içindekisplit, gereksiz tahsisleri kaldırmak için sp_StrArray'i yeniden kullanıyor - Döngü değişmezi uzunluk hoisting'i, sabit yayılımı, 3 ifadeden kısa yöntemlerin otomatik inline edilmesi, yinelenen çıkarımın erken sonlandırılması (~%14 bootstrap süresi kısalması) gibi çok sayıda derleme zamanı optimizasyonu içeriyor
- Üretilen ikililer sıfır runtime bağımlılığı ile geliyor; yalnızca libc + libm ile çalışabiliyor
eval, metaprogramlama, Thread ve Mutex gibi özellikler desteklenmiyor (yalnızca Fiber destekleniyor)- MIT lisansı
1 yorum
Hacker News yorumları
Bunu Matz yaptıysa, Ruby semantics sınırlarını da çok iyi biliyordur; bu yüzden güven veriyor
Benim yüksek lisans tezim de bir AOT JS compiler üzerineydi; çalışıyordu ama girdi verisi kısıtları çok büyüktü, sonunda bıraktım
O dönemde JS geliştiricileri bu tür kısıtları kendi kendilerine disiplinle korumaya pek alışık değildi ve
JSON.parsegibi doğası gereği bilinemez girdiler engel oluyorduBugün TypeScript sayesinde bu iş o zamana göre çok daha gerçekçi olabilir
Sıradan lambda calculus örneklerine bakınca bile type inference sınırları açıkça görülüyor; Matt Might tarafındaki makalelerde ve Shed-skin Python çalışmalarında da benzer kısıtlar ortaya çıkıyor
eval,send,method_missing,define_methodgerçek Ruby kodunda ne kadar yaygın merak ediyorum; typesız parse etme, örneğin JSON girdisi, genelde nasıl ele alınıyor onu da merak ediyorumRuby parse etmek, çevirinin kendisinden bile zor sayılacağı için Prism kullanıyorlar ve çıktı olarak C üretiyorlar
Temel Ruby semantics uygulamasının kendisi o kadar da zor değil
Buna karşılık ben, tamamen Ruby ile yazılmış eski bir self-hosting AOT compiler ile uğraşıyorum; kendi parser'ını yazmakta ısrar ettiği için bilerek çok daha zor bir yolu seçmiş
Erken dönemde, ilk %80'i kabaca yapınca bile epey Ruby kodunun çalıştığını öğrendim; asıl zor olan “ikinci %80” ise Matz'ın bu projede ve mruby'de dışarıda bıraktığı şeylerde, örneğin encoding veya türlü çevresel özelliklerde toplanıyor
Açıkçası Ruby'de gerçek kodda bir kez bile görmediğim epey özellik var; bazıları deprecated olsa şaşırmam
send,method_missing,define_methodçok yaygınKısıtlar mruby'ye benziyor ve bu kısıtlar altında bile kullanım alanı var
send,method_missing,define_methoddesteği görece kolayBuna karşılık eval() desteği inanılmaz sancılı
Yine de Ruby'de
eval()kullanımının büyük bir kısmı, statik olarak instance_eval'in block sürümüne indirgenebiliyor; o durumda AOT derleme oldukça kolaylaşıyorÖrneğin
eval()içine giden string statik olarak bilinebiliyor ya da parçalanabiliyorsa, çözüm ihtimali çok artıyorGerçekte birçok
eval()kullanımı gereksiz ya da basit introspection etrafından dolaşma gibi; bunlar statik analizle ele alınabiliyorBenim derleyicimde de darboğaz orası olursa önce oraya dokunmayı düşünüyorum
Typesız JSON ingestion da muhtemelen bu mekanizmaları kullanıyordur
Bunları çıkarınca geriye Crystal kadar güçlü tipli olmayan ama resmi Ruby kadar da metaprogramming'e yaslanmayan, küçük ve okunabilir bir dil kalıyor
O yüzden potansiyeli epey yüksek görünüyor ama sonuçta zaman gösterecek
evalkullanan taraftayımKullanmadan da yapabilirim ama bana göre bu daha ergonomic
eval,exec,define_methodveClass.new,Struct.newile yeni sınıf oluşturma kalıplarıBunların çoğu uygulama boot aşamasında ya da dosyalar require edilirken kullanılıyor ve bir açıdan zaten derleme aşamasına benziyor
Bu, Matz'ın RubyKaigi 2026'da az önce tanıttığı şey
Deneysel ama Claude yardımıyla yaklaşık bir ayda yapılmış ve canlı demo da başarılı olmuş
Adını Matz'ın yeni kedisinden alıyor; kedinin adı da Card Captor Sakura'daki bir kediden geliyor ve orada da Ruby adlı karakterle eşleşiyor
Matz gibi biri için bu, 100x'i 500x'e çıkarmak bile olabilir
https://en.wikipedia.org/wiki/Spinel
Video sanırım henüz canlı değil; buradaki kanala tek tek yükleniyor gibi
https://www.youtube.com/@rubykaigi4884/videos
Proje adı da sanki duygusal bir tepkiyle seçilmiş gibi
Belli ki çok etkileyici ama AI agent olmadan bakımı imkânsız gibi görünüyor
spinel_codegen.rb21 bin satır ve bazı metotlar 15 seviye iç içe gidiyorDerleyici kodunun güzel olması zaten zor ama bu, o standarda göre bile insanın sürdürebileceği gibi görünmüyor
Derleyicilerde alt sistem sınırları nettir ve aşamalar arası aktarım açık olur; hatta en kolay modular yapılabilen alanlardan biridir
Sorun genelde önce bir şekilde çalıştırıp sonra refactor etmeye vakit bulamamaktır; o zaman da dağınıklık büyüyüp kalır
spinel_codegen.rbneredeyse eldritch horror seviyesindeClaude kullandığımda bende de hep böyle spagetti kod çıkıyor; ben mi yanlış yapıyorum diye düşünüyordum
Ama çok üst düzey saydığım bir programcının yaptığı gerçekten ilginç projede bile kod kalitesinin yer yer oldukça kötü olduğunu görünce, bunun sadece bana özgü olmadığını fark ettim
Örneğin
infer_comparison_type()en kötü örnek değil, hatta okunamaz da sayılmaz; ama çok daha basit ve net bir uygulama mümkünken Claude oraya gidemiyorKarşılaştırma operatörlerini bir
Setiçine koyupinclude?ile kontrol etmek daha kısa, daha hızlı, daha okunur ve daha kolay bakımı yapılır bir çözüm olurduAma Claude hep if-return zincirine kayıyor; hatta sanki if-else bile ona yabancıymış gibi
Benim Claude kod tabanım da bu tür kalıplarla dolu; artık bunun sadece bana özgü olmadığını görüyorum
Buna karşılık diğer dosyalar çok daha iyi; özellikle
libdizini, ana Ruby reposundakiextdizinine karşılık geliyor gibi ve kalitesi iyiAPI de belli ki MRI Ruby'den etkilenmiş; uygulama oldukça farklı olsa bile Matz, özgün API'nin bazı yönlerine benzeterek çıktıyı daha derli toplu hale getirmiş gibi
[1] https://github.com/matz/spinel/blob/98d1179670e4d6486bbd1547...
Testler ve benchmark'lar geçiyorsa şimdilik yeter
Ama böylesine büyük dosyaların AI için de gerçekten işlenebilir olup olmadığı ayrı bir soru
Ben dosyaları 300 satır altında tutmaya çalışıyorum ve insanın anlamasını kolaylaştıran kodun coding agents için de daha kolay olacağını düşünüyorum
Kısıtlar şöyle deniyor
No eval:
eval,instance_eval,class_evalNo metaprogramming:
send,method_missing,define_method(dinamik)No threads:
Thread,Mutex(Fiber destekleniyor)No encoding: UTF-8/ASCII varsayımı
No general lambda calculus:
[]çağrısıyla birlikte derin iç içe-> x { }UTF-8/ASCII varsayımı bana göre büyük bir kısıt değil ama geri kalanı epey çok program için gerçek kısıt gibi duruyor
Ve bunları tekrar eklemek de ciddi emek gerektirecek gibi
Uzun zamandır Ruby kullanıyorum ve sayılan özelliklerin hepsini de kullandım; buna rağmen evrimin sonunda istediğim şeyin aslında böyle bir basit Ruby sürümü olduğunu düşünüyorum
Daha basit ve anlaşılır ama Ruby'ye özgü estetik hâlâ korunuyor
Artık LLM'ler sayesinde kod üretim verimliliği o kadar arttı ki, eskisi gibi geliştirici verimliliği için metaprogramming ile boilerplate azaltma ihtiyacı daha az
Çünkü geliştiricinin doğrudan kod yazdığı pay zaten azalıyor
Sözdizimi benzer ve statik type system var; bu da daha verimli derlenmiş koda götürüyor
evalolmaması bence daha iyi bile ama threads ve mutexes olmaması üzücüdefine_methodeksikliğini kullanım alanı düşünülünce anlayabiliyorumAma
sendvemethod_missingmevcut kütüphanelerde yaygın ve derleme zamanında bir bellek lookup table kurarak uygulanmaları da o kadar zor görünmüyorO yüzden bunlar bilerek mi çıkarıldı, yoksa henüz sıra mı gelmedi emin değilim
Umarım ikincisidir ama en azından şu anda, uyumluluk yüzünden bunu üretimde kullanmak zor görünüyor
Okunacak kod miktarını azaltmaktı
Bu gerçekten harika ve ben uzun zamandır Ruby için bir AOT compiler bekliyordum
Yine de
evalya da metaprogramming fallback'inin olmaması biraz üzücü; ama belli ki küçük ve yüksek performanslı bir subset'e odaklanmak için bu seçilmişUmarım bu AOT compiler ile üretilen gem'ler MRI ile iyi etkileşir
Standart Ruby ve gem'leri paketleme ya da bundle etme tarafında ise hâlâ tebako, kompo, ocran gerekiyor; geçmişte ruby-packer, traveling ruby, jruby warbler gibi projeler de vardı
Bir seçeneğin daha olması güzel ama daha iyi geliştirici UX'i olan nihai sürümün çıkmasını umuyorum
Çünkü çok uzun süredir güncellenmiyordu
No threads neden denmiş merak ediyorum
Ruby scheduler ve alttaki pthread implementasyonu C tarafında da gayet çalışır gibi geliyor; acaba zero dependency hedefi mi var?
Sonradan gelecek optional extension olarak düşünülmüyorsa ya da henüz eksik bırakılmadıysa, bu tercih biraz tuhaf hissettiriyor
Muhtemelen sadece daha oraya sıra gelmemiştir
Multithreading'i düzgün yapmak zaten başlı başına çok zor
Bir aydan biraz fazla sürede yapılmış olması şaşırtıcı
AI hakkında ne denirse densin, işi bilen bir geliştiricinin elinde muazzam bir hız artışı sağlıyor
Matz ise sanki sadece
gem env|infovefindile yetiyormuş gibiBunu Matz yaptığına göre, gelecekte Ruby core'un bir parçası olma ihtimali ne kadar gerçekçi merak ediyorum
Ve eğer olursa Crystal için ne kadar tehdit oluşturur onu da merak ediyorum
Bu özellikler büyük programları derlemek ve bakımını yapmak için neredeyse vazgeçilmez
Buna karşılık bu proje Ruby'nin sınırlı bir subset'ine yönelik; dolayısıyla popüler Ruby gem'lerinin çoğu doğrudan çalışmayacaktır
C'ye derlenen bir dil subset'i olması bakımından PreScheme'e daha yakın görünüyor
Şu anda ikisinin doğrudan aynı alanda rekabet ettiğini düşünmüyorum
Tam Ruby için büyük olasılıkla yine JIT gerekecek
[1]: https://prescheme.org/
Bu da Rational Unified Process ve Enterprise Architect gibi araçların bir tür rövanşı olur
Fark şu olur: UML diyagramları yerine markdown dosyaları gelir
Bunun infrastructure tools tarafında faydalı olabileceğini düşünüyorum
Mesela Ruby ile yazılmış ama statik derlenen bir bundler hayal edin; böylece RVM gibi Ruby kurulum araçlarının rolünü de üstlenebilir
Mevcut Ruby buildpack'leri Ruby ile yazılmış olsa da bootstrap için bash gerekmesi can sıkıyor ve edge case'ler doğuruyor
CNB bu sorunu aşmak için Rust ile yazıldı ve bağımlılığı olmayan tek bir binary dağıtabilme fikri gerçekten çok güçlü