- Sekitar 3 tahun lalu, saat menulis sendiri bytecode VM dan garbage collector dengan Zig dan unsafe Rust, ergonomi yang ramah bagi manusia dari Zig lebih unggul, tetapi saat memasuki era coding agent, keunggulan itu pada dasarnya menjadi tidak berarti
- Peningkatan produktivitas developer sebesar 1,5~5x yang diberikan fitur-fitur utama Zig kalah telak oleh peningkatan produktivitas 100x dari coding agent berbasis Rust
- Fitur inti Zig seperti allocator interface, integer dengan lebar bit arbitrer, packed struct, dan comptime semuanya bersinar saat manusia menulis kode secara langsung
- Sistem tipe Rust lebih efektif untuk mencegah kesalahan agent saat compile time melalui bounded polymorphism dan penegakan invariant
- Dalam situasi ketika jumlah kode yang dihasilkan agent meningkat 100x, jaminan keamanan memori Rust menjadi keunggulan yang menentukan dibanding Zig
Perubahan inti
- Zig punya keunggulan besar dalam ergonomi kode unsafe, tetapi karena porsi kode yang ditulis langsung oleh manusia berkurang, nilai praktis keunggulan itu juga mengecil
- Peningkatan produktivitas developer manusia di kisaran 1,5~5x yang diberikan fitur Zig tertutupi oleh peningkatan 100x dari penggunaan coding agent di Rust
- Sebagian besar fitur khas Zig meningkatkan kenyamanan saat manusia menulis kode dengan tangan, tetapi perbedaan itu tidak terlalu penting bagi coding agent
- Sekitar 3 tahun lalu, saat menulis bytecode VM dan garbage collector dengan Zig dan unsafe Rust, pengalaman menulis kode unsafe terasa lebih baik di Zig
- Bahkan menurut standar 2026, Zig tetap bahasa yang bagus, tetapi Rust berubah menjadi bahasa yang lebih disukai dan juga lebih cocok dengan coding agent
Interface allocator Zig
- Interface allocator Zig memudahkan penerapan allocator khusus seperti arena atau stack fallback untuk mengoptimalkan jalur kode tertentu
- Saat membaca satu baris input pengguna, panjang input secara teori tak terbatas sehingga membutuhkan heap allocator, tetapi pada praktiknya kebanyakan input hanyalah query pencarian atau path pendek sehingga jauh lebih kecil dari 1KB
std.heap.stackFallback(256, heap_allocator) menempatkan buffer berukuran tetap di stack, lalu hanya beralih ke heap saat input melampaui kapasitas, sehingga kasus umum dapat diproses tanpa alokasi heap
- Di Rust dulu tidak ada fitur yang setara dengan interface
Allocator milik Zig, sehingga jika membutuhkan Vec<T> yang memakai allocator kustom, implementasi pustaka standar harus disalin lalu dimodifikasi
- Source collection Bumpalo berbentuk fork dari collection standar yang dihubungkan ke bump allocator
- Di Rust nightly, trait
Allocator sempat tersedia cukup lama, dan sekarang tampak sudah mencapai tingkat yang cukup baik
Allocator di Rust berbasis trait sehingga memakai static dispatch, berbeda dengan allocator Zig yang berbasis vtable
- Rust tidak punya konvensi komunitas yang luas untuk merancang struktur data berdasarkan parameter allocator seperti Zig, tetapi karena AI makin mudah menyalin lalu mengubah kode, keterbatasan ini menjadi kurang penting
Integer lebar bit arbitrer dan packed struct
- Integer lebar bit arbitrer dan
packed struct di Zig memudahkan pekerjaan seperti optimasi cache CPU bergaya data-oriented design, tagged pointer, NaN boxing, dan bitflags
- Saat memakai API Obj-C bersama Metal melalui Objective-C runtime C API,
id bisa berupa tagged pointer, bukan pointer objek heap yang ter-align
- Jika
NSNumber bertag diteruskan ke kode yang mengasumsikan alignment, UB bisa terjadi, sehingga perlu pemeriksaan murah untuk membedakan “pointer heap atau immediate bertag”
- Dalam tata letak tagged pointer Objective-C yang disederhanakan, 1 bit terendah menandakan “bukan pointer heap”, 3 bit berikutnya mengidentifikasi slot kelas, dan 60 bit sisanya menjadi payload
- Zig dapat memakai
enum(u3) dan packed struct untuk merepresentasikan layout bit langsung sebagai tipe, misalnya class: TaggedClass, payload: u60
- Di Zig,
@bitCast memungkinkan konversi bolak-balik antara u64 mentah dan ObjcTaggedPointer, dan di is_ns_number bisa diperiksa is_tagged serta kelas .ns_number
- Kode padanan Rust menaruh konstanta seperti
TAG_MASK, CLASS_MASK, CLASS_SHIFT, dan PAYLOAD_SHIFT di dalam ObjcTaggedPointer(u64), lalu memakai operasi OR saat membuat nilai dan mask saat mengaksesnya
- Di Rust, slot kelas bukan tipe sungguhan melainkan konstanta
u64, dan pendekatan tulis tangan ini kurang ergonomis dibanding Zig
- Di Rust lebih baik memakai crate seperti bitfield atau bitflags, tetapi keduanya bergantung pada proc macro dan tetap tidak terasa sebaik
packed struct milik Zig
- Dengan adanya coding agent, masalah bahwa kode seperti ini merepotkan untuk ditulis manual jadi jauh berkurang
Perubahan nilai comptime
- comptime Zig adalah fitur yang paling mencolok, dan selain beberapa bahasa dependent type yang sulit dipahami, hampir tidak ada bahasa yang memberikan evaluasi compile time sebaik Zig
- Dalam penggunaan nyata, comptime tidak lagi terlalu dirindukan, dan sekitar 95% penggunaan dipakai untuk membuat struktur data generik bertipe terparameterisasi
- Pola seperti
fn ArrayList(comptime T: type) type, yang menerima tipe lalu mengembalikan tipe struct dengan items: []T, capacity: usize, dan allocator: Allocator, adalah contoh yang representatif
- Sistem tipe Rust menggantikan sebagian besar generic comptime ala Zig dan dapat menegakkan lebih banyak kondisi invariant
- Pada sekitar 5% kasus sisanya, ketiadaan comptime terasa merepotkan, dan satu-satunya alternatif andal hanyalah codegen
- Saat ingin meng-hardcode data hitbox geometry yang dihasilkan tool selama pengembangan game ke dalam struktur data, di Rust perlu meminta Claude menulis skrip yang menghasilkan file Rust
- Meski begitu, evaluasi compile time sebenarnya tidak terlalu sering dibutuhkan
Kelebihan sistem tipe Rust
- Sistem tipe Rust dinilai sebagai pertukaran yang lebih bernilai daripada comptime milik Zig, terutama kuat di area traits/typeclasses untuk bounded polymorphism
- Jika mencoba mengimplementasikan bounded polymorphism setara di Zig, hal itu akan sangat sulit
- Sistem tipe Rust dapat menegakkan lebih banyak kondisi invariant, sehingga membantu mencegah kesalahan yang sering dibuat coding agent
- Dalam kode game, crate euclid dipakai untuk mencegah kebingungan ruang koordinat, masalah yang umum dalam pemrograman grafis
- Dengan membuat tipe khusus untuk tiap ruang koordinat seperti
Point<Screen> atau Point<World>, pencampuran koordinat world dan screen secara tidak sengaja bisa dicegah pada tahap kompilasi
- Jika
WorldPoint, WorldVector, dan ScreenPoint dijadikan tipe terpisah, maka penjumlahan point dan vector dalam ruang yang sama tetap diperbolehkan
- Melalui
Translation2D::<f32, WorldSpace, ScreenSpace>, dapat dilakukan konversi eksplisit dari ruang world ke ruang screen
- Sebaliknya, kode seperti
let bad: ScreenPoint = player; yang langsung menempatkan WorldPoint ke ScreenPoint tidak diizinkan
Efek lebih jarang menangani masalah memori
- Jika coding agent memungkinkan penulisan kode 100x lebih banyak, maka jumlah kode Zig yang perlu ditinjau untuk masalah memori juga meningkat 100x
- Tanpa verifikasi formal, luas ruang pencarian yang harus diperiksa untuk menemukan bug menjadi jauh lebih besar
- Dalam situasi sekarang, ketika volume kode yang dihasilkan sangat besar, Rust menjadi lebih menarik
- Trade-off tradisional Rust adalah produktivitas developer bisa terganggu saat belum terbiasa dengan borrow checker, tetapi dengan adanya coding agent, pentingnya kekurangan ini jauh berkurang
- Bahkan saat memakai
unsafe di Rust, coding agent dapat diminta menjalankan alat seperti miri untuk memeriksa apakah UB terjadi dan apakah aturan aliasing Rust dilanggar
Kesimpulan
- Zig tetap bahasa yang dirindukan dan tetap bahasa yang bagus
- Dalam cara kerja tahun 2026, Rust lebih disukai, dan kecocokannya dengan coding agent juga lebih baik
1 komentar
Pendapat di Lobste.rs
Seorang lead tim saya dulu punya pandangan yang cukup kuat bahwa kode copy-paste tidak selalu buruk
Karena prinsip DRY, secara naluriah terdengar salah atau setidaknya kontroversial, tetapi dia orang yang sangat pragmatis, dan prinsip ini terutama dia terapkan pada codebase pengujian yang besar
Logikanya, daripada memaksakan antarmuka bersama yang "cerdas", codebase yang sederhana tetapi lebih besar dan lebih banyak duplikasinya justru bisa lebih mudah dipelihara
Belakangan ini, setelah memakai LLM, saya kembali ke pemikiran yang sama, dan sekarang bahkan menerapkannya pada bagian software yang lebih penting
Pembuatan kode itu cepat, dan LLM juga tampaknya lebih mungkin tepat pada codebase yang sederhana tetapi banyak duplikasi
Kalau terlalu banyak abstraksi dimasukkan ke pengujian demi mengurangi duplikasi, pengujian jadi lebih sulit dipahami, dan risikonya juga bisa salah secara halus
Yang lebih buruk, kalau abstraksi dari kode yang diuji dipakai ulang, pengujiannya juga bisa salah dengan cara yang sama seperti kode itu
Selain itu, tidak seperti kode aplikasi, pengujian pada dasarnya bisa “dikomposisikan” secara gratis
Selama Anda tidak merusak test harness secara parah, Anda bisa menambah atau menghapus pengujian sesuka hati tanpa memengaruhi pengujian lain, dan karena tidak ada friction integrasi, satu alasan lagi untuk menghindari duplikasi jadi hilang
Untuk pengujian, saya pernah melihat ini dijelaskan sebagai DAMP: “Descriptive and Meaningful Phrases”, prinsip yang menekankan keterbacaan daripada keunikan
Prinsip ini memang bisa menghasilkan duplikasi berupa pengulangan kode yang mirip, tetapi membuat pengujian tampak lebih jelas benar
https://testing.googleblog.com/2019/12/…
Di komunitas Go juga ada ungkapan serupa: “a little copying is better than a little dependency” https://go-proverbs.github.io/
Saya bersyukur dia membagikan live coding-nya
Kalau ingatan saya benar, saat memulai sesuatu dia sering mencari kode yang paling mirip dengan yang ingin dia buat, menyalinnya utuh, lalu memodifikasinya dari sana
Saya sempat berpikir, “Kok tidak duduk dulu memikirkan abstraksi yang sama-sama dimiliki keduanya?” tetapi dia cukup lanjut saja dengan copy-paste dan jauh lebih produktif daripada saya
Menarik kalau memikirkan timing penulisan ulang AI Zig → Rust milik Bun https://xcancel.com/jarredsumner/status/2053063524826620129#m
Disebutkan bahwa 75 di antaranya tidak akan bisa dikompilasi dalam bahasa yang punya destruktor, move semantics, dan borrow checker
Artinya, satu dari tiga PR yang dirilis adalah “lupa membebaskan resource di jalur error”
Dari 108 itu, sekitar 88 ada di Zig, sedangkan sekitar 14 di sisi C++ kebanyakan termasuk kategori sisa yang akan tetap ada dalam bahasa apa pun, seperti reference cycle dan race konkurensi GC
Jadi perbedaan Zig→Rust itu nyata, bug di Zig memang tepat jenis yang bisa diperbaiki dengan destruktor dan ownership, sementara sisi C++ sudah mendekati batas bawah
Tanpa jaminan compile-time yang lebih kuat, ini akan tetap jadi permainan kucing dan tikus
Usulannya adalah, alih-alih terus memperbaiki kategori bug terbesar satu per satu, lebih baik menghilangkannya secara struktural
– bun/docs/rust-rewrite-plan.md at claude/phase-a-port · oven-sh/bun · GitHub
Bagian “untuk 5% kasus sisanya, tanpa comptime semuanya menyiksa, dan satu-satunya cara untuk reliably mencapai hasil yang setara adalah code generation” tidak jelas maksud penulisnya
Karena dia sama sekali tidak membahas procedural macro
comptimemilik Zig memang sangat keren, tetapi sistem makro Rust juga sama sekali bukan sesuatu yang bisa diremehkanMemang agak merepotkan untuk dibuat dengan baik, tetapi banyak hal bisa dilakukan dengannya
Saya juga merasa code generation kadang mendapat reputasi buruk tanpa alasan
Saya sudah cukup sering menyelesaikan masalah-masalah menjengkelkan dengan code generation lewat skrip
build.rs, dan hasilnya berjalan baikTentu saja, mungkin nanti saya akan menyesalinya
Argumen inti tulisan itu kira-kira terlihat seperti ini
Rust memang bahasa yang bagus, tetapi tetap saja ini agak berlebihan
Terlihat seperti iklan agen coding
Ini berasal dari tulisan tertaut oleh penulis yang sama: kesalahan yang sangat umum dalam pemrograman grafis adalah mencampuradukkan ruang koordinat, dan sistem tipe cukup kuat untuk mengekspresikan lewat tipe ruang koordinat mana yang sedang dipakai dan transformasi mana yang valid
Hal yang sama juga berlaku untuk mata uang, satuan SI versus jarak dan berat imperial, string yang telah divalidasi versus string dari pengguna dan secret
Juga, bila dikelola dengan baik, state type bisa mencegah state yang mustahil atau tidak sound
Tetapi secara pribadi, fitur yang paling saya inginkan dari Rust adalah penghapusan total data race
Bahasa terkelola pun tetap punya data race
Kalimat “pakai Go saja” — di Go semuanya mutable lewat referensi antar-thread, lengkap dengan akrobat slice
Bahkan JavaScript, yang dulu benar-benar bahasa mainan meski termasuk yang paling murni dan aman, setiap
awaitadalah race potensialBelum lagi kejahatan dari pola everything-is-an-EventEmitter
Jadi ya, benar. Kalau saja ada GC… 🤫
Rasanya inti masalahnya agak disamarkan
Agen coding juga sangat mahir menangani Python dan JavaScript
Apakah lebih baik daripada Rust itu wilayah yang sangat subjektif, tetapi tetap saja saya tidak akan memilih bahasa-bahasa itu untuk banyak pekerjaan
Saya jadi penasaran apakah masalahnya ada pada fitur Zig yang sering berubah, atau sekadar karena ini bahasa yang lebih baru sehingga data pelatihan AI-nya kacau
Menurut saya Zig lebih sulit ditulis daripada Rust, tetapi lebih mudah dibaca
Di era AI, kode yang dibaca lebih banyak daripada kode yang ditulis, jadi saya cenderung memilih Zig
Melihat jumlah kode yang sekarang dihasilkan, mengatakan Rust lebih menarik hanyalah langkah pertama
Semakin banyak komputer yang menulis kode, semakin bahasa formal akan diuntungkan
Ini terasa seperti tahap lain dari perdebatan tipe dinamis
Kurang lebih seperti, “tipe dinamis lebih mudah bagi manusia, jadi mengapa hal yang sama harus dinyatakan tiga kali demi mesin?”
Tipe, lifetime… apa lagi yang lebih mudah ditulis dan dikonsumsi mesin?
Saya penasaran seberapa sulit nantinya manusia menulis langsung dalam bahasa yang dipakai komputer masa depan untuk menulis kode