1 poin oleh GN⁺ 21 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Ini adalah eksperimen proyek pribadi untuk memindahkan crate web app Rust ke Ruby on Rails, dengan target kode berbasis Tera dan Axum sebanyak 14.943 baris
  • Konfigurasi Rust yang ada saat ini membutuhkan Playwright E2E, namespace database terisolasi, layanan mock, hingga crate API internal, sehingga biaya pengujian menjadi tinggi
  • Dalam perbandingan LLM, Rails memperoleh total skor 710, lebih tinggi daripada Rust/Axum/Diesel yang mendapat 480, dan dinilai unggul dalam kecepatan pengembangan serta kemudahan unit test
  • Konversi sekali jalan menggunakan Local Qwen3.6 memakan waktu sekitar 30 menit, dan kode Ruby menyusut menjadi 3.322 baris, tetapi belum diverifikasi dengan menjalankannya
  • Rails unggul dalam fitur bawaan dan pengujian yang ringkas, sementara kurangnya stabilitas tipe di Ruby dapat dilengkapi dengan Sorbet atau penambahan tipe berbasis agen

Latar belakang eksperimen migrasi

  • Sebagian dari proyek pribadi, yaitu crate web app Rust, dipilih sebagai target migrasi ke Ruby on Rails
    • Seluruh proyek berukuran sekitar 30 ribu baris, dan crate yang dimigrasikan lebih dekat ke sebuah web app yang ditulis dengan Tera dan Axum
    • Kode Rust yang menjadi target migrasi berjumlah total 14.943 baris, dan kompilasinya memakan waktu sekitar 10 detik
    • Kodenya sendiri tidak besar, tetapi strukturnya membawa banyak dependensi
  • Konfigurasi Rust yang ada memiliki biaya pengujian yang tinggi
    • Pengujian E2E memerlukan konfigurasi Playwright
    • Karena mocking sulit dilakukan, dibutuhkan namespace database yang terisolasi dan layanan mock
    • Juga diperlukan crate API internal terpisah agar Playwright dapat berinteraksi dengan aplikasi dalam mode headless
  • Ruby dan Ruby on Rails dipertimbangkan sebagai alternatif yang lebih ringkas
    • Ruby tidak memiliki tipe, sehingga stabilitasnya bisa lebih rendah dibanding Rust
    • Dengan menggunakan Sorbet, stabilitas tipe di Ruby dapat dilengkapi sebagian
  • Hasil perbandingan kompleksitas, stabilitas, kemudahan pengujian, dan lain-lain menggunakan beberapa instance LLM menunjukkan skor Rails lebih tinggi
    • Total Rust/Axum/Diesel adalah 480, Rails 710, dan Rails + Sorbet 695
    • Rails dinilai tinggi dengan skor 90 untuk kecocokan bagi pengembang individu, 90 untuk kecepatan pengembangan, dan 90 untuk kemudahan unit test
    • Rust/Axum/Diesel unggul dengan skor 95 untuk keamanan dan 95 untuk performa, tetapi rendah pada kemudahan unit test 20 dan kemudahan integration test 30
    • Berdasarkan jumlah sederhana, aplikasi Rails dinilai dapat menghasilkan hasil yang 1,47 kali lebih baik

Hasil migrasi dan poin yang perlu ditinjau

  • Proyek yang relatif kecil dikonversi sekali jalan menggunakan Local Qwen3.6
    • Proses konversi memakan waktu sekitar 30 menit
    • Karena belum dijalankan, belum dapat dipastikan apakah benar-benar berfungsi
  • Perubahan terbesar adalah penurunan jumlah baris kode
    • Total baris file Rust: 14.943 baris
    • Total baris file Ruby: 3.322 baris
    • Jumlah baris berkurang 77%, dan 1 baris Ruby setara dengan sekitar 4,49 baris Rust
  • Kode Ruby hasil konversi, sejauh yang sudah ditinjau sekilas, tampak bersih dan idiomatis
    • Kemungkinan bug masih ada
    • Akan ditinjau lebih teliti setelah ini
  • Poin tinjauan tambahan adalah pelengkapan tipe, fitur bawaan Rails, dan penyederhanaan pengujian
    • Jika tipe ditambahkan dengan bantuan agen, masalah stabilitas tipe dapat dikurangi
    • Ruby/Rails dinilai lebih dekat ke “batteries + kitchen sink included”, dan lebih baik daripada dependensi terkompilasi berukuran 3GiB
    • Pengujian diperkirakan akan menjadi jauh lebih mudah
  • Contoh pengujian Ruby berbentuk singkat, membungkus panggilan LLM dengan VCR.use_cassette("llm_call") lalu memverifikasi ukuran hasil
      VCR.use_cassette("llm_call") do
        result = LlmClient.match(entry, data_list)
        expect(result.results.size).to eq(data_list.size)
      end
    
  • Contoh pengujian Rust berbentuk lebih panjang karena harus mengimplementasikan provider mock secara langsung
    • Menggunakan Arc<RwLock<Vec<Response>>>, AtomicUsize, async_trait, tokio::test, dan lainnya
    • Membuat MockProvider yang mengelola daftar respons dan jumlah pemanggilan, lalu mengimplementasikan match pada trait Provider dan memverifikasi hasil serta jumlah pemanggilan dalam pengujian
  • Karena ini proyek pribadi, pilihan yang berani bisa diambil, dan migrasi dari Rust ke Ruby akan ditinjau lebih mendalam ke depannya

1 komentar

 
GN⁺ 21 jam lalu
Komentar Hacker News
  • Sulit dipercaya. Kedengarannya seperti, “Ada rasa gatal teknis yang ingin saya garuk, lalu AI lokal menyelesaikan pekerjaannya dalam 30 menit. Saya bahkan tidak menekan Start untuk melihat apakah ini benar-benar jalan, tapi saya tetap menulis postingan blog…”

    • Fakta bahwa ini ada di peringkat 1 halaman depan saat ini berarti tidak masalah apakah proyeknya benar-benar berfungsi atau tidak. Pembacanya juga pasti tidak benar-benar membaca artikelnya
      tentu saja kalau ini bukan didorong naik oleh bot
    • 2016: Tolong lihat library JavaScript baru saya!
      2026: Tolong lihat hasil kerja yang bukan saya yang menulisnya!
      2036: Cara saya menulis 200 baris dalam bahasa Latin kuno bernama C
    • Bukan sekadar “sulit dipercaya”, ini malah terasa cukup biasa untuk ukuran tahun 2026
    • Tapi dia memang meninjau hasilnya selama 5 jam. Jadi ¯\(ツ)
  • Awalnya saya kira ini akan jadi tulisan yang menarik, tapi begitu sampai pada bagian bahwa dia memakai LLM untuk konversinya, minat saya langsung hilang. Mirip seperti, “Saya ingin melakukan ini jadi saya suruh bawahan saya mengerjakannya, lalu sekarang saya akan ceritakan itu kepada Anda”
    Dia juga tidak melakukan konversinya sendiri atau memikirkannya secara mendalam, jadi rasanya tidak ada alasan kuat untuk membacanya

    • Masalah terbesarnya adalah penulisnya bahkan tidak memverifikasi hasilnya. Saya pernah melihat alat besar yang menggabungkan beberapa model menjalankan konversi selama 6 jam, lalu saat diperiksa manual bagaimana ia menangani perhitungan atau logika yang rumit, ternyata ada stub atau pengembalian true yang di-hardcode
      Jadi kalau cuma menjalankan smoke test, hasilnya bisa tampak seperti sukses
    • Masalah yang lebih besar adalah bahwa pengembangan perangkat lunak ke depan memang akan bergerak seperti ini
      Di luar pemrograman yang benar-benar bersifat kerajinan, bahasa pemrograman itu sendiri jadi tidak terlalu penting
      Semakin baik LLM, pada akhirnya ini hanya akan menjadi soal memilih spesifikasi itu ingin dihasilkan dalam bahasa jenis apa
      Kubu UML dan RUP akhirnya berhasil membalas dendam
    • Intinya bukan apakah dia menulis kodenya sendiri atau tidak, tetapi bahwa dia melihat perbedaannya lalu membuat pilihan yang mungkin tidak optimal
      Seperti sudah disebut di komentar lain, dia sudah meninjaunya cukup luas. Ini juga bukan proyek besar, jadi selain beberapa bagian pedas, sebagian besar cuma aplikasi web
      Menilai bahwa dia “tidak berpikir” menurut saya tidak adil. Ini bukan sekadar menekan tombol lalu YOLO
      Dia meneliti trade-off dan hasilnya, perbedaan antara potongan kode Rust dan Rails memang besar, dan soal keterujian aplikasi Rust itu sendiri sudah menjadi topik yang dia pikirkan selama 2 bulan
      Seperti kata para penggemar LLM, konteks itu penting ;)
  • Saya tidak yakin ada bahasa dan framework lain yang memprioritaskan kebahagiaan developer sebesar Ruby on Rails

    • Hampir tidak pernah saya merasa sebegitu sengsara seperti saat bekerja di proyek Rails. Saya melihat bug di situs, lalu menjalankan grep untuk mencari view yang salah render. Saya menemukan pemanggilan method yang merender bagian itu, lalu grep lagi berdasarkan nama method tersebut, hasilnya 0
      Berarti ada sesuatu yang disusun secara dinamis di suatu tempat dan saya tidak tahu di mana, lalu akhirnya saya berhenti dari pekerjaan utama saya dan membaca dokumentasi selama satu jam. Mungkin ini oke bagi orang yang memakai Rails sepanjang hari, tapi convention over configuration adalah antipola raksasa bagi saya
    • Saya merasakan nuansa yang mirip di Elixir dan Phoenix, hanya saja tanpa alat untuk menembak kaki sendiri bernama method_missing
    • Meski mungkin tidak tampak menarik bagi komunitas dengan selera ala Silicon Valley, saya juga pernah bekerja cukup puas dengan framework Java dan .NET
      Kebahagiaan tidak selalu berujung pada performa. Saya jadi teringat kasus logo terkenal Twitter sebelum mereka pindah ke JVM dan Scala
      Ruby on Rails memang jadi terkenal, tetapi pengalaman serupa sudah ada sebelumnya di AOLServer berbasis Tcl dan Vignette
      Di startup Portugal pun mereka membuat variasi sendiri, dan para pendirinya kemudian membuat OutSystems. Itu adalah salah satu alat RAD grafis awal untuk pengembangan situs web dan sistem terdistribusi, dengan pendekatan low-code/no-code yang menargetkan infrastruktur JVM atau CLR
      Meski begitu, saya senang melihat sekarang CRuby dengan JIT hadir secara bawaan
    • Paling-paling itu cuma kebahagiaan jangka pendek, dengan harga yang dibayar berupa semua karakteristik arsitektur lain seperti maintainability, performa, keandalan, skalabilitas, dan seterusnya
  • Saya sudah membuat kumpulan gem bernama propel_rails yang mendorong kode Ruby on Rails yang memang sudah ringkas ke level yang lebih ekstrem. Ia membuat kelas tingkat atas seperti API controller dan concern, lalu dari situ menghasilkan seluruh resource RESTful (model, controller, serializer, unit test, dan E2E test) tanpa boilerplate sama sekali
    Pada akhirnya controller hanya berisi daftar atribut yang diizinkan API, karena action RESTful dibuat otomatis. Agak sulit menjelaskannya secara tuntas, tetapi kekuatan metaprogramming Ruby memang membuat hal-hal luar biasa jadi mudah

    • Kedengarannya seperti bentuk CRUD yang dimurnikan
      Apakah ini bisa dipahami sebagai sesuatu yang bekerja berdasarkan model domain?
    • Saya bisa menemukannya di rubygems, tetapi tautan GitHub yang terhubung dari sana menghasilkan 404
  • Saya berada di situasi yang mirip
    Saya suka Go dan Rust, keduanya bahasa yang hebat dengan plus minusnya masing-masing. Tapi sayangnya saya tidak pernah berhasil membangun aplikasi SaaS dengan salah satunya. Rasanya seperti memasukkan pasak persegi ke lubang bundar
    Bisa jadi saya sangat keliru, tetapi alat SaaS punya banyak perangkat bawaan, dan saya tidak ingin menemukan ulang semua itu
    RoR itu “cukup bagus”. Anda bisa menambahkan tipe saat dibutuhkan, bisa membangun dengan cepat, dan tooling-nya juga lumayan
    Pekerjaan profesional pertama saya adalah PHP, dan jebakannya terlalu banyak. Ruby terasa sedikit lebih condong ke ranah e-commerce jadi menarik, dan kalau cukup baik untuk Shopify, bagi saya itu sudah oke

  • Jika situasinya memang masuk akal untuk berpindah dari Rust ke Ruby, berarti memilih Rust sejak awal adalah kesalahan

    • Ini ringkasan yang sangat bagus untuk artikel itu, dan juga alasan saya memutuskan membagikannya
  • Orang yang mengira Ruby lebih lambat dari Rust mungkin akan terkejut saat tahu bahwa Ruby sekarang sebenarnya lebih cepat daripada Python, meski tetap lebih lambat daripada Go atau Rust

    • Biasanya penggunaan memori lebih penting daripada kecepatan. Sebagian besar aplikasi Ruby dibatasi kecepatannya bukan oleh Ruby, melainkan oleh database
      Tetapi kalau ada beberapa background worker dan masing-masing mulai memakan lebih dari 2GB memori, akumulasinya cepat sekali terasa
      Saya pernah menulis satu layanan Rust produksi, dan yang lebih mengesankan daripada kecepatannya adalah layanan itu berjalan dengan memori 30MB
    • Saya tidak mengerti kenapa orang yang mengira Ruby lebih lambat dari Rust harus terkejut mengetahui bahwa Ruby lebih cepat dari Python. Apa hubungannya?
  • Ini memang omongan yang provokatif, tetapi walau bagus untuk pamer IQ 900+ ke rakyat jelata di sekitar, banyak developer cerdas dan berbakat justru tidak terlalu suka Rust. Sebagian bahkan memilih membuat bahasa pemrograman dan kompiler mereka sendiri daripada menulis satu baris Rust
    Saya jadi teringat Jai buatan Jonathan Blow dan Odin buatan Ginger Bill
    Masih banyak juga orang lain yang kreativitas dan kedalamannya sudah terbukti, yang membuat library dan framework indah yang dipakai luas, tapi saya tidak ingin membuang ruang di sini
    Hanya saja, Rust memang punya klub macho yang keren sekaligus persaudaraan yang erat

    • Komunitas Rust justru sejauh mungkin dari kesan “klub macho”
  • Claude benar-benar bekerja sangat baik untuk aplikasi Rails. Seperti yang juga disorot penulis artikel ini, Ruby memungkinkan banyak hal dilakukan dengan sedikit kode, dan Rails memakai convention over configuration, sehingga aplikasi Rails jadi lebih ringkas
    Salah satu hipotesis kenapa Claude menulis aplikasi Rails dengan baik adalah efisiensi token
    Saya pernah melihat proyek ini yang mencoba mengukur dan membandingkan efisiensi token per proyek, dan Rails menunjukkan hasil yang cukup bagus
    https://felipemrvieira.github.io/SyntaxTax/dashboard/

  • Saya kadang heran melihat ukuran proyek. Codebase 30 ribu baris itu kecil? Saya tahu batas atasnya bisa jauh lebih tinggi, tapi 30 ribu baris sudah bisa memuat sangat banyak informasi dan nuansa perilaku
    Mungkin ini karena latar belakang saya yang lebih fokus ke backend/jaringan dengan Go. Setelah melewati 10 ribu sampai 15 ribu baris, biasanya sudah cukup berat untuk tetap menyimpan model keseluruhan codebase di kepala

    • Ini sangat tergantung pada apa yang dibuat. Aplikasi SaaS dengan beberapa frontend bisa dengan mudah mencapai 30 ribu baris