1 poin oleh GN⁺ 9 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Mengubah kode Ruby menjadi binary native mandiri, dan menargetkan eksekusi dengan rata-rata geometri sekitar 11,6x lebih cepat dibanding CRuby miniruby terbaru melalui inferensi tipe pada tingkat seluruh program dan pembuatan kode C
  • Pipeline kompilasi mengubah Ruby menjadi teks AST dengan parser berbasis Prism, lalu backend self-hosting melakukan inferensi tipe dan pembuatan kode C, kemudian membuat binary standalone dengan kompiler C standar
  • Backend kompiler memiliki arsitektur self-hosting yang ditulis dalam Ruby, dan setelah melalui proses bootstrap, gen2.c == gen3.c terpenuhi sehingga loop untuk mengompilasi dirinya sendiri tertutup
  • Menambahkan optimisasi waktu kompilasi seperti perataan konkatenasi string, value-type promotion, loop-invariant length hoisting, static symbol interning, dan auto-promotion bigint, serta mengurangi ketergantungan runtime eksternal dengan regexp engine bawaan, bigint, dan runtime header tunggal
  • Tidak mendukung eval, metaprogramming, Thread, maupun penanganan encoding umum, tetapi bentuk distribusi yang dapat berjalan tanpa Ruby dan perbedaan performa besar pada workload intensif komputasi menunjukkan sisi praktis kompilasi AOT untuk Ruby

Cara kerja

  • Pipeline kompilasi terdiri dari alur yang mem-parsing file Ruby, menserialisasikannya menjadi file teks AST, lalu melalui inferensi tipe dan pembuatan kode C untuk menghasilkan binary native dengan kompiler C standar
  • spinel_parse menggunakan Prism dan libprism untuk mem-parsing Ruby, dan ketika binary C tidak tersedia, ia memakai jalur alternatif yang menggunakan CRuby dan gem Prism
  • spinel_codegen berjalan sebagai binary native self-hosted, menerima AST dan melakukan inferensi tipe + pembuatan kode C
  • Tahap akhir mengompilasi source C bersama header runtime dengan cc -O2 -Ilib -lm, dan binary hasilnya dibuat dalam bentuk standalone

Self-Hosting

  • Rantai bootstrap ditutup dengan cara membuat AST memakai CRuby + spinel_parse.rb, lalu membuat gen1.c dan bin1 dengan CRuby + spinel_codegen.rb, kemudian memakai binary yang dihasilkan untuk membuat gen2.c dan gen3.c
  • gen2.c == gen3.c terpenuhi, yang menandakan bootstrap loop telah tertutup
  • Backend spinel_codegen.rb ditulis menggunakan subset Ruby yang dapat dikompilasi langsung oleh Spinel
    • classes, def, attr_accessor
    • if/case/while
    • each/map/select, yield
    • begin/rescue
    • operasi String, Array, Hash, dan File I/O
  • Backend tidak memasukkan metaprogramming, eval, maupun require

Performa dan benchmark

  • Pengujian berada pada status 74 lolos, benchmark pada status 55 lolos
  • Berdasarkan 28 benchmark, rata-rata geometri sekitar 11,6x lebih cepat dibanding CRuby miniruby terbaru
  • Patokan perbandingan adalah build CRuby miniruby terbaru tanpa bundled gem, dan bahkan jika dibandingkan dengan patokan yang lebih cepat daripada ruby 3.2.3 sistem, keunggulannya tetap besar pada workload intensif komputasi
  • Performa komputasi

    • life: 20ms vs 1.733ms, 86,7x lebih cepat
    • ackermann: 5ms vs 374ms, 74,8x lebih cepat
    • mandelbrot: 25ms vs 1.453ms, 58,1x lebih cepat
    • versi rekursif fib: 17ms vs 581ms, 34,2x lebih cepat
    • nqueens: 10ms vs 304ms, 30,4x lebih cepat
    • tarai: 16ms vs 461ms, 28,8x lebih cepat
    • tak: 22ms vs 532ms, 24,2x lebih cepat
    • matmul: 13ms vs 313ms, 24,1x lebih cepat
    • sudoku: 6ms vs 102ms, 17,0x lebih cepat
    • partial_sums: 93ms vs 1.498ms, 16,1x lebih cepat
    • fannkuch: 2ms vs 19ms, 9,5x lebih cepat
    • sieve: 39ms vs 332ms, 8,5x lebih cepat
    • fasta: 3ms vs 21ms, 7,0x lebih cepat
  • Struktur data dan GC

    • rbtree: 24ms vs 543ms, 22,6x lebih cepat
    • splay tree: 14ms vs 195ms, 13,9x lebih cepat
    • huffman: 6ms vs 59ms, 9,8x lebih cepat
    • so_lists: 76ms vs 410ms, 5,4x lebih cepat
    • binary_trees: 11ms vs 40ms, 3,6x lebih cepat
    • linked_list: 136ms vs 388ms, 2,9x lebih cepat
    • gcbench: 1.845ms vs 3.641ms, 2,0x lebih cepat
  • Program nyata

    • json_parse: 39ms vs 394ms, 10,1x lebih cepat
    • perhitungan 1000 digit bigint_fib: 2ms vs 16ms, 8,0x lebih cepat
    • ao_render: 417ms vs 3.334ms, 8,0x lebih cepat
    • pidigits: 2ms vs 13ms, 6,5x lebih cepat
    • str_concat: 2ms vs 13ms, 6,5x lebih cepat
    • template engine: 152ms vs 936ms, 6,2x lebih cepat
    • csv_process: 234ms vs 860ms, 3,7x lebih cepat
    • io_wordcount: 33ms vs 97ms, 2,9x lebih cepat

Fitur Ruby yang didukung

  • Fitur Core mendukung classes, inheritance, super, mixin include, attr_accessor, Struct.new, alias, konstanta module, dan open classes untuk tipe bawaan
  • Control Flow mendukung if/elsif/else, unless, case/when, pattern matching case/in, while, until, loop, for..in, break, next, return, catch/throw, dan &.
  • Blocks mendukung yield, block_given?, &block, proc {}, Proc.new, -> x { }, method(:name), serta method blok seperti each, map, select, reduce, sort_by, times, upto, downto
  • Exceptions mendukung begin/rescue/ensure/retry, raise, dan kelas exception kustom
  • Types mencakup Integer, Float, String, Array, Hash, Range, Time, StringIO, File, Regexp, Bigint, Fiber
    • nilai polimorfik ditangani sebagai tagged unions
    • menyediakan nullable object types T? untuk struktur data yang mereferensikan dirinya sendiri
  • Global Variables mengompilasi $name menjadi variabel C statis, dan ketidakcocokan tipe dideteksi saat kompilasi
  • I/O mendukung puts, print, printf, p, gets, ARGV, ENV[], File.read/write/open, system(), dan backtick

String, regexp, symbol, Bigint, Fiber

  • Strings menangani string immutable dan mutable, dan << otomatis dipromosikan menjadi string mutable sp_String untuk melakukan append in-place O(n)
  • +, interpolation, tr, ljust/rjust/center, dan method standar bekerja pada kedua representasi string
  • Perbandingan seperti s[i] == "c" dioptimalkan agar langsung mengakses array char sehingga diproses tanpa alokasi
  • Konkatenasi seperti a + b + c + d diratakan menjadi satu pemanggilan sp_str_concat4 atau sp_str_concat_arr, sehingga mengurangi N-1 alokasi
  • str.split(sep) di dalam loop menggunakan ulang sp_StrArray yang sama, dan pada csv_process terjadi penghapusan 4 juta alokasi
  • Regexp menggunakan NFA regexp engine bawaan tanpa dependensi eksternal
    • mendukung =~, $1-$9, match?, gsub, sub, scan, split
  • Bigint menggunakan integer presisi arbitrer berbasis mruby-bigint
    • dipromosikan otomatis pada pola seperti perkalian berulang dalam loop seperti q = q * k
    • ditautkan sebagai library statis dan hanya disertakan saat benar-benar digunakan
  • Fiber menyediakan konkurensi kooperatif berbasis ucontext_t
    • mendukung Fiber.new, Fiber#resume, Fiber.yield, dan pengiriman nilai
    • variabel bebas ditangkap sebagai cell yang dipromosikan ke heap
  • Symbols diimplementasikan sebagai tipe sp_sym yang terpisah dari string
    • mempertahankan :a != "a"
    • literal symbol di-intern saat kompilasi menjadi konstanta SPS_name
    • String#to_sym memakai pool dinamis hanya saat diperlukan
    • hash dengan key symbol memakai sp_SymIntHash untuk menyimpan key integer secara langsung alih-alih string, sehingga strcmp dan alokasi string dinamis hilang

Manajemen memori dan value type

  • Manajemen memori menggunakan mark-and-sweep GC, termasuk size-segregated free lists, non-recursive marking, dan sticky mark bits
  • Kelas yang kecil dan sederhana otomatis dipromosikan menjadi value types dan ditempatkan di stack
    • syaratnya maksimal 8 field skalar
    • tidak ada inheritance
    • tidak dimodifikasi melalui parameter
  • Alokasi kelas dengan 5 field sebanyak 1 juta kali turun dari 85ms menjadi 2ms
  • Program yang hanya memakai value type tidak mengekspor runtime GC sama sekali

Optimisasi

  • Berdasarkan inferensi tipe tingkat seluruh program, Spinel menjalankan berbagai optimisasi waktu kompilasi
  • Value-type promotion membuat kelas kecil yang immutable menjadi objek stack struct C sehingga menghilangkan overhead GC
  • Constant propagation meng-inline konstanta literal sederhana seperti N = 100 langsung di titik penggunaan tanpa lookup cst_N
  • Loop-invariant length hoisting membuat while i < arr.length menghitung panjang hanya sekali sebelum loop
    • jika body mengubah receiver seperti arr.push, hoist ini dinonaktifkan
  • Method inlining menambahkan static inline pada method pendek non-rekursif dengan 3 statement atau kurang untuk mendorong inlining oleh gcc
  • String concat chain flattening mereduksi rantai konkatenasi menjadi satu pemanggilan sehingga pembuatan string perantara hilang
  • Bigint auto-promotion otomatis mempromosikan pola penjumlahan self-referential atau perkalian berulang menjadi bigint
  • Bigint to_s memakai mpz_get_str dari mruby-bigint untuk pemrosesan divide-and-conquer O(n log²n)
  • Static symbol interning mengubah "literal".to_sym menjadi konstanta waktu kompilasi SPS_<name>, dan hanya menambahkan pool runtime saat interning dinamis dipakai
  • Pada sub_range, string dengan panjang yang sudah di-hoist memakai sp_str_sub_range_len untuk melewati pemanggilan internal strlen
  • line.split(",") di dalam loop menggunakan ulang sp_StrArray yang sudah ada
  • Dead-code elimination memakai -ffunction-sections -fdata-sections dan --gc-sections untuk membuang fungsi runtime yang tidak digunakan dari binary akhir
  • Iterative inference early exit langsung menghentikan loop fixed-point jika tiga array signature untuk parameter, return, dan ivar tidak lagi berubah
    • sebagian besar program konvergen dalam 1–2 iterasi penuh, bukan 4 iterasi
    • waktu bootstrap berkurang sekitar 14%
  • parse_id_list byte walk mengganti parser daftar field AST yang dipanggil sekitar 120 ribu kali saat self-compile dari s.split(",") ke iterasi manual s.bytes[i], menurunkan alokasi per panggilan dari N+1 menjadi 2
  • Kode C yang dihasilkan mempertahankan warning-free build pada level warning default, dan harness memakai -Werror agar regresi langsung terlihat

Arsitektur

  • Struktur repositori dibagi menjadi komponen berikut
    • spinel: skrip wrapper satu perintah berbasis POSIX shell
    • spinel_parse.c: frontend C 1.061 baris dari libprism ke AST teks
    • spinel_codegen.rb: backend kompiler 21.109 baris dari AST ke kode C
    • lib/sp_runtime.h: header library runtime 581 baris
    • lib/sp_bigint.c: integer presisi arbitrer 5.394 baris
    • lib/regexp/: regexp engine bawaan 1.759 baris
    • test/: 74 functional test
    • benchmark/: 55 benchmark
    • Makefile: otomatisasi build
  • Runtime lib/sp_runtime.h menempatkan implementasi GC, array/hash/string, dan dukungan runtime lainnya dalam satu file header
  • Kode C yang dihasilkan meng-include header ini, dan linker hanya mengambil bagian yang diperlukan dari libspinel_rt.a
    • bigint
    • regexp engine
  • Parser memiliki dua implementasi
    • spinel_parse.c menaut langsung ke libprism dan berjalan tanpa CRuby
    • spinel_parse.rb adalah fallback CRuby yang memakai gem Prism
  • Kedua parser menghasilkan output AST yang sama, dan wrapper spinel memprioritaskan binary C bila memungkinkan
  • require_relative diselesaikan saat parsing sehingga file yang dirujuk di-inline

Batasan

  • No eval: eval, instance_eval, class_eval tidak didukung
  • No metaprogramming: send, method_missing, define_method dinamis tidak didukung
  • No threads: Thread dan Mutex tidak didukung, hanya Fiber yang didukung
  • No encoding: mengasumsikan UTF-8 dan ASCII
  • No general lambda calculus: tidak menangani pemanggilan -> x { } dan [] yang sangat bertingkat

Dependensi dan model eksekusi

  • Dependensi saat build adalah library C libprism dan CRuby untuk bootstrap awal
  • Tidak ada dependensi runtime, dan binary hasil hanya membutuhkan libc + libm
  • Regexp menggunakan engine bawaan sehingga tidak memerlukan library eksternal
  • Bigint sudah dibundel, tetapi hanya ditautkan saat benar-benar digunakan
  • Prism adalah parser Ruby yang dipakai spinel_parse
    • make deps mengunduh tarball gem prism dari rubygems.org dan mengekstrak source C ke vendor/prism
    • jika gem prism sudah terpasang, ia akan terdeteksi otomatis
    • jalur kustom juga bisa ditentukan dengan PRISM_DIR=/path/to/prism
  • CRuby hanya diperlukan untuk bootstrap awal, dan setelah make, seluruh pipeline berjalan tanpa Ruby

Riwayat proyek

  • Spinel awalnya diimplementasikan dalam C, berukuran 18K lines, dan masih tersisa di branch c-version
  • Setelah itu, proyek melewati branch ruby-v1 yang ditulis ulang dalam Ruby
  • master saat ini adalah versi yang kembali ditulis ulang dengan subset Ruby yang dapat self-hosting

Lisensi

  • Menggunakan MIT License
  • Mengikuti file LICENSE

1 komentar

 
GN⁺ 9 jam lalu
Komentar Hacker News
  • Karena ini buatan Matz, rasanya lebih mudah dipercaya karena dia pasti paham betul batasan semantics Ruby
    Tesis master saya juga dulu tentang AOT JS compiler, dan memang sempat jalan, tapi akhirnya saya hentikan karena batasan pada data input terlalu besar
    Waktu itu para developer JS belum terbiasa disiplin menjaga batasan semacam itu, dan input yang secara inheren tidak bisa diketahui seperti JSON.parse menjadi penghambat utama
    Sekarang, berkat TypeScript, mungkin ini jauh lebih realistis dibanding saat itu
    Bahkan kalau hanya melihat lambda calculus umum, batas inferensi tipe sudah jelas, dan pembatasan serupa juga terlihat di paper-paper Matt Might maupun proyek Shed-skin Python
    Saya penasaran seberapa sering eval, send, method_missing, dan define_method muncul di kode Ruby nyata, dan juga bagaimana biasanya input parsing tanpa tipe, misalnya input JSON, ditangani

    • Desain ini tampak cukup pragmatic
      Parsing Ruby bahkan bisa lebih sulit daripada proses translasi itu sendiri, jadi mereka memakai Prism, lalu menghasilkan C sebagai output
      Semantics dasar Ruby sendiri sebenarnya tidak sampai sesulit itu untuk diimplementasikan
      Sebaliknya, saya sedang berkutat dengan self-hosting AOT compiler lama yang ditulis dalam Ruby murni, dan karena saya ngotot memakai parser buatan sendiri, saya sengaja memilih jalan yang jauh lebih sulit
      Saya belajar sejak awal bahwa 80% pertama bisa dibuat asal jalan saja dan ternyata sudah cukup untuk menjalankan banyak kode Ruby, sedangkan “80% kedua” yang benar-benar sulit terkumpul pada hal-hal yang dihilangkan Matz dari proyek ini dan dari mruby, misalnya encoding dan segala fitur pinggiran lain
      Jujur saja, Ruby punya cukup banyak fitur yang belum pernah saya lihat dipakai di kode nyata, jadi saya rasa tidak aneh kalau beberapa di antaranya akhirnya deprecated
      send, method_missing, dan define_method sangat umum
      Batasannya mirip mruby, dan tetap ada kegunaannya bahkan dengan batasan seperti itu
      Dukungan untuk send, method_missing, dan define_method relatif mudah
      Sebaliknya, dukungan eval() sangat menyakitkan
      Namun, porsi besar eval() di Ruby sebenarnya bisa direduksi secara statis menjadi versi blok dari instance_eval, dan dalam kasus seperti itu AOT compilation jadi cukup mudah
      Misalnya, kalau string yang masuk ke eval() bisa diketahui atau diurai secara statis, ruang penyelesaiannya jadi jauh lebih besar
      Dalam praktiknya, banyak penggunaan eval() itu sebenarnya tidak perlu atau hanya semacam jalan memutar untuk introspection sederhana, jadi bisa ditangani lewat analisis statis
      Di compiler saya juga, kalau itu menjadi bottleneck, saya akan mulai menanganinya dari sana
    • Fitur seperti ini memang perlu cukup banyak untuk membuat magic ala Rails
      Ingestion JSON tanpa tipe kemungkinan besar juga memakai mekanisme seperti itu
      Kalau itu semua dibuang, yang tersisa adalah bahasa yang kecil dan mudah dibaca, tidak seketat Crystal dalam typing, tapi juga tidak terlalu bergantung pada metaprogramming seperti Ruby resmi
      Jadi potensinya terlihat cukup besar, tapi tetap saja baru bisa dinilai seiring waktu
    • Kalau Ruby dikompilasi ke Objective-C, sepertinya semua fitur Ruby bisa tetap didukung sambil tetap lebih cepat daripada Ruby interpreter
    • Saya termasuk yang sering memakai eval
      Bisa saja tidak dipakai, tapi buat saya itu lebih ergonomic
    • Dari pengalaman saya, hal yang menarik itu eval, exec, define_method, serta pola membuat class baru dengan Class.new dan Struct.new
      Sebagian besar penggunaannya terkonsentrasi saat boot aplikasi atau ketika file di-require, jadi dalam beberapa hal itu sudah mirip tahap kompilasi
  • Ini adalah sesuatu yang baru saja diumumkan Matz di RubyKaigi 2026
    Memang masih eksperimental, tapi dibuat hanya dalam waktu sekitar sebulan dengan bantuan Claude, dan live demo-nya juga berhasil
    Namanya diambil dari kucing baru Matz, dan nama kucing itu sendiri berasal dari nama kucing di Card Captor Sakura, yang di sana juga dipasangkan dengan karakter bernama Ruby

    • Orang sering bicara soal AI yang membuat program sepenuhnya dari awal sampai akhir, tapi menurut saya skenario yang lebih realistis adalah menjadikan 10x programmer menjadi 100x programmer
      Untuk orang seperti Matz, mungkin malah seperti mendorong 100x menjadi 500x
    • Di kepala saya, Spinel yang paling melekat justru yang dari Steven Universe, jadi saya sama sekali tidak menangkap Spinel/Ruby (Moon) pun-nya, tapi setelah tahu, hari saya jadi lebih menyenangkan
    • Saya jelas mengira yang dimaksud adalah mineral spinel :)
      https://en.wikipedia.org/wiki/Spinel
    • Terima kasih
      Sepertinya videonya belum live, dan tampaknya sedang diunggah satu per satu ke channel ini
      https://www.youtube.com/@rubykaigi4884/videos
    • Cerita soal asal-usul nama kucing itu terasa cukup mencurigakan kalau mengingat drama Ruby Central dan hubungan dengan para pendiri Spinel.coop
      Nama proyeknya juga terasa dipilih secara emosional
  • Ini jelas sangat mengesankan, tapi tampaknya mustahil dipelihara tanpa AI agent
    spinel_codegen.rb panjangnya 21 ribu baris, dan beberapa metodenya sampai bertingkat 15 level
    Kode compiler memang sulit dibuat indah, tapi bahkan dengan standar itu pun, ini terlihat sangat sulit dikelola oleh manusia

    • Kode compiler sebenarnya bisa dibuat cukup indah kalau ada waktu
      Compiler punya batas subsistem yang jelas dan handoff antartahap yang tegas, jadi justru termasuk salah satu jenis sistem yang paling mudah dibuat modular
      Masalahnya biasanya setelah berhasil dibuat jalan, tidak ada waktu lagi untuk refactor, lalu kekotorannya terus menumpuk
    • spinel_codegen.rb nyaris setingkat eldritch horror
      Saat memakai Claude, saya juga selalu mendapatkan spaghetti code seperti ini, jadi saya sempat bertanya-tanya apakah saya melakukan sesuatu yang salah
      Tapi setelah melihat bahwa proyek yang benar-benar menarik buatan orang yang saya anggap programmer kelas atas pun kualitas kodenya cukup buruk di beberapa bagian, saya jadi tahu bahwa bukan cuma saya
      Misalnya, infer_comparison_type() bukan contoh terburuk dan juga tidak terlalu sulit dibaca, tapi sebenarnya ada implementasi yang jauh lebih sederhana dan jelas, hanya saja Claude gagal menuju ke sana
      Kalau operator perbandingan dikumpulkan dalam Set lalu diproses dengan include?, hasilnya akan lebih pendek, lebih cepat, lebih mudah dibaca, dan lebih gampang dirawat
      Tapi Claude selalu cenderung jatuh ke rantai if-return, bahkan terkesan asing dengan if-else biasa
      Codebase Claude saya juga penuh dengan pola seperti itu, dan sekarang saya sadar saya tidak sendirian
      Sebaliknya, file-file lain jauh lebih baik, terutama direktori lib, yang tampaknya berkorespondensi dengan direktori ext di repo Ruby utama dan kualitasnya cukup bagus
      API-nya juga jelas dipengaruhi MRI Ruby, dan meskipun implementasinya cukup berbeda, tampaknya Matz mengarahkan agar sebagian API-nya menyerupai API asli sehingga output-nya terasa lebih rapi
      [1] https://github.com/matz/spinel/blob/98d1179670e4d6486bbd1547...
    • Pada tahap sekarang, saya rasa apakah manusia bisa memeliharanya secara manual belum terlalu penting
      Selama tes dan benchmark lolos, saya sudah cukup puas
      Tapi saya ragu file raksasa seperti itu mudah ditangani bahkan oleh AI
      Saya mencoba membatasi file di bawah 300 baris, dan saya pikir kode yang mudah dipahami manusia juga akan lebih mudah dipahami coding agents
  • Batasannya katanya seperti ini
    No eval: eval, instance_eval, class_eval
    No metaprogramming: send, method_missing, define_method (dinamis)
    No threads: Thread, Mutex (Fiber didukung)
    No encoding: asumsi UTF-8/ASCII
    No general lambda calculus: -> x { } bertingkat dalam dengan pemanggilan []
    Asumsi UTF-8/ASCII secara pribadi bukan batasan besar bagi saya, tapi sisanya tampaknya akan jadi batasan nyata untuk cukup banyak program
    Dan untuk menambahkan semua itu lagi tampaknya perlu pekerjaan yang lumayan besar

    • Kalau begitu, banyak bagian dari magic Ruby jadi hilang
  • Sebagai orang yang sudah lama memakai Ruby dan pernah menggunakan semua fitur yang disebutkan itu, justru versi Ruby yang sederhana seperti inilah yang akhirnya saya inginkan setelah sekian lama berevolusi
    Lebih sederhana dan lebih mudah dipahami, tapi tetap menyisakan rasa estetika khas Ruby
    Sekarang, berkat LLM, produktivitas pembuatan kode sudah begitu tinggi sehingga kita tidak lagi terlalu perlu mengurangi boilerplate lewat metaprogramming demi produktivitas developer seperti dulu
    Karena porsi kode yang benar-benar ditulis langsung oleh developer sendiri juga makin berkurang

    • Kalau yang Anda cari cuma aesthetic Ruby, Crystal mungkin juga cocok
      Sintaksnya mirip dan punya static type system, jadi bisa menghasilkan kode hasil kompilasi yang lebih efisien
    • Tidak adanya eval menurut saya justru lebih baik, tapi ketiadaan threads dan mutexes terasa sayang
      Tidak adanya define_method masih bisa dimengerti kalau melihat kegunaannya
      Tapi send dan method_missing umum di library yang sudah ada, dan implementasinya rasanya tidak terlalu sulit, misalnya dengan membangun memory lookup table saat compile time
      Jadi saya tidak tahu apakah itu sengaja dihilangkan, atau mereka memang belum sampai ke sana
      Saya berharap yang kedua, tapi setidaknya untuk saat ini tampaknya sulit dipakai di produksi karena masalah kompatibilitas
    • Kelebihan metaprogramming pada dasarnya bukan menulis kode lebih sedikit
      Melainkan mengurangi jumlah kode yang perlu dibaca
  • Ini benar-benar keren, dan saya sudah lama menunggu AOT compiler untuk Ruby
    Tapi sayang tidak ada fallback untuk eval atau metaprogramming, meski tampaknya itu memang keputusan untuk fokus pada subset kecil yang berkinerja tinggi
    Akan bagus kalau gem yang dibuat dengan AOT compiler ini bisa berinteraksi dengan baik dengan MRI
    Untuk sisi packaging atau bundling Ruby standar dan gem, kita masih butuh tebako, kompo, dan ocran, dan dulu juga ada proyek seperti ruby-packer, traveling ruby, dan jruby warbler
    Senang ada satu opsi lagi, tapi saya tetap berharap akan muncul solusi pamungkas dengan UX developer yang lebih baik

    • Betul, saya juga baru-baru ini harus mem-fork warbler
      Karena terlalu lama tidak diperbarui
  • Saya penasaran kenapa no threads
    Ruby scheduler dan implementasi pthread di bawahnya rasanya tetap bisa berjalan baik di ranah C, jadi saya sempat berpikir mungkin tujuannya zero dependency
    Kalau bukan extension opsional yang rencananya akan ditambahkan nanti atau sekadar belum diimplementasikan, pilihan ini terasa agak aneh

    • Saya belum melihat bukti bahwa mereka secara sengaja memutuskan untuk tidak mendukungnya
      Kemungkinan besar memang baru belum sampai ke sana
      Multithreading memang dari awal sangat sulit dibuat dengan benar
  • Mengejutkan bahwa ini dibuat hanya dalam waktu sedikit lebih dari sebulan
    Apa pun pendapat orang soal AI, di tangan developer yang kuat, itu benar-benar bisa menghasilkan percepatan yang luar biasa

    • Seluruh industri sibuk memulai dengan agent harness, SOUL.md, pengaturan izin, skills, MCPs, hooks, env, dan sebagainya
      Sementara Matz terasa seperti cukup dengan gem env|info dan find
  • Karena ini dibuat oleh Matz, saya penasaran seberapa realistis kemungkinan bahwa ini nantinya menjadi bagian dari Ruby core
    Dan kalau itu terjadi, saya juga penasaran seberapa besar ancamannya terhadap Crystal

    • Crystal punya static type system yang eksplisit dan dioptimalkan untuk AOT compilation di level bahasa
      Karakteristik seperti ini nyaris wajib untuk mengompilasi dan memelihara program besar
      Sementara ini hanya subset Ruby yang terbatas, jadi sebagian besar gem Ruby populer kemungkinan tidak akan langsung berjalan apa adanya
      Sebagai subset bahasa yang menargetkan kompilasi ke C, ini tampak lebih dekat ke PreScheme
      Pada tahap sekarang, saya tidak melihat keduanya bersaing langsung di ranah yang sama
      Ruby yang benar-benar penuh hampir pasti tetap membutuhkan JIT
      [1]: https://prescheme.org/
    • Dari sudut pandang lain, pada akhirnya LLM tampaknya akan sampai pada titik di mana ia bisa menghasilkan formal specification dalam bahasa apa pun yang kita inginkan
      Ini semacam momen balas dendam untuk tool seperti Rational Unified Process dan Enterprise Architect
      Bedanya cuma, yang datang nanti bukan diagram UML melainkan file markdown
  • Ini sepertinya akan berguna di area infrastructure tools
    Misalnya, bayangkan ada bundler yang ditulis dalam Ruby tapi dikompilasi secara statis, sehingga sekaligus bisa berperan seperti alat instalasi Ruby ala RVM
    Buildpack Ruby yang sekarang memang ditulis dalam Ruby, tapi bootstrap-nya harus lewat bash sehingga merepotkan dan memunculkan edge case
    CNB ditulis dalam Rust untuk menghindari masalah itu, dan gagasan mendistribusikan single binary tanpa dependency benar-benar sangat kuat