Apakah Rust Sepadan?
(medium.com/@jsoverson)- Setelah berpindah dari JavaScript ke Rust demi fokus pada WebAssembly, selama 3 tahun penulis membangun Wick, deployment produksi, ebook, dan sekitar 100 paket di crates.io, lalu menilai nilai nyata Rust
- borrow checker, sistem tipe yang kaya, pola fungsional, dan ketiadaan
nullmencegah banyak bug di tahap kompilasi sehingga memungkinkan basis kode besar dengan lebih sedikit pengujian - Clippy dan Cargo workspace sangat kuat, tetapi celah pada tool dan ekosistem seperti konfigurasi lint global dan publish workspace berujung pada biaya operasional
- async, refactoring, dan pengelolaan generic·lifetime·trait constraint tetap menjadi area dengan gesekan lebih besar dibanding JavaScript atau Go
- Rust tangguh dan serbaguna, tetapi biaya perekrutan, pembelajaran, iterasi cepat, dan pelacakan masalah tinggi, sehingga lebih cocok ketika cakupan sudah jelas atau biaya awalnya bisa ditanggung
WebAssembly mendorong pemilihan Rust
- Beberapa tahun lalu, penulis meninggalkan pekerjaan yang ada untuk fokus 100% pada WebAssembly, dan saat itu Rust memiliki dukungan kompilasi WebAssembly terbaik
- Runtime WebAssembly yang kaya fitur juga banyak berbasis Rust, sehingga di antara pilihan yang ada, Rust menjadi opsi paling realistis
- Setelah itu, penulis membuat Wick, framework aplikasi sekaligus runtime yang menggunakan WebAssembly sebagai sistem modul inti
- Selama 3 tahun, pengalaman Rust terkumpul lewat berbagai deployment produksi, ebook, dan publikasi sekitar 100 paket di crates.io
Memelihara lebih banyak kode dengan lebih sedikit pengujian
- Di Rust, penulis menulis pengujian seperti di bahasa lain pada umumnya, lalu menyadari bahwa jika kodenya bisa dikompilasi, beberapa pengujian itu praktis tidak mungkin gagal
- Dengan menghindari blok
unsafe {}dan method yang mudah memicu panic seperti.unwrap(), banyak masalah pada dasarnya bisa dihindari - borrow checker, sistem tipe yang kaya, pola dan library fungsional, serta tidak adanya nilai
nullmengurangi upaya yang dibutuhkan untuk pengujian - Proyek Wick dengan lebih dari 70.000 baris kode dipelihara dengan pengujian yang jauh lebih sedikit dibanding yang biasanya dibutuhkan di bahasa lain
- Saat pengujian memang diperlukan, harness pengujian integrasi Rust memudahkan penambahan tes tepat di samping kodenya
Rust juga mengubah kebiasaan menulis kode di bahasa lain
- Compiler Rust terus memprotes kode yang di bahasa lain dianggap normal, dan melalui proses itu kebiasaan menulis kode pun berubah
- Kini, bahkan di bahasa lain, penulis merasa tidak nyaman jika urutan baris kode terasa janggal atau nilai kembalian tidak diperiksa
- Saat menemui runtime error pun, penulis kini merasakan penolakan yang jauh lebih kuat dibanding sebelumnya
- Keketatan Rust memang tidak nyaman, tetapi setelah terbiasa dengan pengalaman dilindungi compiler, sulit untuk kembali ke bahasa lain
Clippy berguna lebih dari sekadar linter
- Clippy adalah linter untuk Rust, tetapi lebih terasa sebagai alat bantu yang ramah yang menyarankan kode pengganti, bukan sekadar alat pemeriksa
- Standard library Rust sangat besar, dan karena fungsinya tersebar di banyak type, trait, macro, dan function, API yang dibutuhkan sering sulit ditemukan
- Sejumlah aturan menemukan pola umum yang bisa digantikan dengan method atau type dari standard library yang lebih baik
- Contoh: manual_is_ascii_check
- Ratusan aturan mencakup performa, keterbacaan, dan indirection yang tidak perlu, serta bila memungkinkan juga menyediakan kode pengganti
- Konfigurasi lint global tingkat proyek tampak akan dimungkinkan melalui isu Cargo, tetapi sampai saat itu Wick harus memperbarui konfigurasi lint inline di puluhan crate secara otomatis lewat skrip
Ada celah di ekosistem yang harus diterima
- Masalah konfigurasi global Clippy adalah salah satu contoh celah ekosistem yang sering ditemui di tool dan library Rust
- Isu terkait kini sudah ditutup, tetapi sempat terbuka selama bertahun-tahun dan penyelesaiannya memakan waktu lama
- Rust lama dipilih sebagai “bahasa yang paling dicintai” dan berhasil menarik pengguna baru, tetapi arus itu tidak otomatis langsung menghasilkan peningkatan dramatis pada library dan tool
- Sering muncul fork sekali pakai untuk menangani use case tertentu, dan di Wick pun saat mencoba mengirim PR, penulis mengalami situasi serupa
- Kemungkinan alasannya mencakup tekanan untuk mempertahankan API yang stabil dan sistem tipe yang sangat terperinci
- Pemilik library sulit menerima perubahan kecil karena itu bisa berujung pada perubahan major version
- Menulis kode Rust yang memenuhi kebutuhan semua orang juga merupakan beban besar
Cargo, crates.io, dan gesekan saat publish workspace
- Struktur repositori Wick dibuat dengan merujuk pada proyek-proyek populer dan awalnya terlihat masuk akal, tetapi masalah muncul pada tahap distribusi
- Dengan Cargo, membangun, menguji, dan menggunakan crate berukuran modul itu mudah, tetapi publish ke crates.io adalah persoalan lain
- Di crates.io, semua crate yang dirujuk harus sudah dipublikasikan secara terpisah agar sebuah paket bisa di-publish
- Larangan mem-publish crate yang bergantung pada paket yang hanya ada di filesystem lokal memang masuk akal
- Tetapi pada struktur alami proyek besar yang dipecah menjadi modul internal kecil, sub-crate yang hanya ada di dalam parent crate tidak bisa ikut di-publish bersama
- Ada koreksi bahwa crate dengan local dev dependency tetap bisa di-publish tanpa menyertakan
versiondiCargo.toml - Dukungan Cargo workspace sendiri sangat bagus, dan pengalaman mengelola proyek besar lebih baik daripada kebanyakan bahasa lain
- Namun workspace tidak menyelesaikan masalah distribusi, dan meskipun ada berbagai cara konfigurasi, sulit menemukan “jawaban benar” yang mudah dipublish
- Banyaknya utility crate terkait cargo workspace publish justru menunjukkan adanya masalah itu sendiri
- Saat mem-publish Wick, menggabungkan pekerjaan manual berulang dan tool yang hanya bekerja sebagian sering membuat prosesnya memakan waktu lebih dari 1 jam
async adalah salah satu sumber gesekan terbesar
- async di Rust terasa seperti fitur yang ditambahkan setelah bahasanya selesai dibuat, dan dalam penggunaan nyata pun sering terasa seperti tempelan belakangan
- Error-nya sulit dipahami dan diperbaiki, dan saat mencari solusi pun harus menyaring berdasarkan berbagai runtime serta pendekatan async masing-masing
- Beberapa library async mungkin tidak dapat digunakan di luar runtime async tertentu
- Dari sudut pandang seseorang yang telah 20 tahun memakai JavaScript dan juga punya pengalaman dengan Go, async di Rust adalah sumber frustrasi dan gesekan terbesar
- Ini bukan masalah yang mustahil diatasi, tetapi selalu perlu bersiap bahwa masalah async bisa muncul kapan saja
- Di bahasa lain, async hampir tidak terlihat karena bekerja dengan sangat alami
Refactoring bisa menjadi pekerjaan berat
- Sistem tipe Rust yang kaya adalah kelebihan sekaligus kekurangan
- Berpikir dengan tipe Rust itu baik, tetapi mengelola tipe Rust bisa menjadi mimpi buruk
- Signature data dan function bisa memuat generic type, generic lifetime, dan trait constraint
- Constraint itu sendiri juga bisa memiliki generic type dan lifetime lagi, sehingga terkadang type constraint justru lebih banyak daripada kode sebenarnya
- Contoh: rxRust observable.rs
- Karena generic harus didefinisikan di setiap
impl, penulisan awal pun merepotkan, dan saat refactoring perubahan kecil dapat berkembang menjadi rangkaian perubahan besar- Contoh: Wasmtime Cranelift iter.rs
- Saat daftar constraint atau generic yang sama harus diulang di banyak tempat, tidak ada cara di level bahasa atau tool untuk membuat alias atau merujuk definisi terpusat, sehingga beban duplikasi tetap ada
Penilaian akhir: kuat, tetapi mahal
- Rust sangat serbaguna hingga kode tingkat sistem, aplikasi CLI, web server, dan web client bisa ditulis dalam bahasa yang sama
- Dengan WebAssembly, LLM yang sama dapat dijalankan di browser maupun command line dengan binary yang sama
- Program Rust bisa sangat tangguh, dan setelah merasakan masalah-masalah yang dapat dicegah Rust, sulit untuk kembali ke bahasa lain
- Saat sempat kembali ke Go, kecepatan pengembangan kembali terasa menarik, tetapi setelah mengalami runtime panic, keunggulan itu mulai goyah
- Rust jelas memiliki kekurangan
- Sulit merekrut talenta
- Proses belajar lambat
- Terlalu kaku untuk iterasi cepat
- Sulit melacak masalah memori dan performa, terutama pada kode async
- Tidak semua library cukup baik untuk kode yang aman
- Tool pengembangan masih punya banyak ruang untuk ditingkatkan
- Tim kecil ini berhasil melakukan hal-hal luar biasa, tetapi juga menghadapi hambatan besar, dan karena memang ada alasan teknis yang membuat Rust lebih cocok untuk Wick, penulis menilai masih terlalu dini untuk memutuskan apakah Rust benar-benar sepadan untuk Wick
- Jika harus beriterasi cepat, Rust kemungkinan besar bukan pilihan yang tepat
- Jika cakupan masalahnya sudah diketahui atau biaya awal yang lebih besar bisa ditanggung, Rust layak dipertimbangkan secara serius
- Dari sudut pandang WebAssembly, kemungkinan menulis perangkat lunak tangguh sekali lalu menggunakannya kembali di banyak tempat makin terasa realistis dari bulan ke bulan
1 komentar
Opini di Hacker News
Saya sudah banyak memakai Rust, tetapi setelah beberapa tahun pun masih terasa kurang produktif
Belakangan saya banyak memakai Zig; rasanya sekitar 10x lebih produktif karena saya bisa fokus pada coding yang saya inginkan saja, tanpa perlu bingung harus memakai tool atau library apa
Saya tahu Rust memberi keamanan memori dan itu penting, tetapi kegunaannya benar-benar buruk. Setiap kali memakai Rust, rasanya seperti dibatasi, dan karena selalu harus mencari library atau menelusuri cara mengerjakan sesuatu, saya tidak bisa sekadar “mengetik kode”
Sistem tipenya juga bisa membesar tak terkendali, dan sering kali sulit mengetahui method apa yang sebenarnya bisa dipanggil pada suatu struct. Rust adalah tool yang hebat dan menyelesaikan banyak masalah, tetapi saya tidak menganggapnya bahasa serbaguna yang baik
Sebagai orang yang sudah memakai Python hampir 20 tahun, sekarang saya juga bisa bekerja secepat di Python saat memakai Rust
Menurut saya Rust benar-benar meleset dari titik keseimbangan yang tepat. Untuk menulis aplikasi tingkat tinggi, ia terlalu rewel soal detail tingkat rendah; untuk embedded atau sistem operasi, ia terlalu kompleks
Untuk yang pertama, saya akan memilih C++, Java, Haskell, OCaml, bahkan Go dengan sedikit campuran C; untuk yang kedua, C yang dipakai seperti macro assembler jauh lebih cocok
Saya masih merasa gagasan awal Graydon Hoare—yakni bahasa yang lebih condong ke OCaml/SML dengan linear types, garbage collection, alokasi stack, green thread, dan CPS—akan menjadi bahasa yang jauh lebih baik
Di C, satu kesalahan kecil sering berujung pada undefined behavior dan masalah merepotkan, tetapi di Rust hal seperti itu tidak ada, jadi benar-benar mengubah permainan
Saya juga penasaran apakah maksudnya di Zig Anda tidak perlu mencari library atau mencari tahu cara melakukan sesuatu
Rust memaksa kita memutuskan di awal ke mana setiap bit dan byte pergi, di thread mana dipakai, dan dengan cara mutasi seperti apa ditangani. Kalau bukan di level parser atau microcontroller, proses ini terasa membosankan
Saya suka pendekatan membuat sesuatu berjalan dulu lalu menentukan struktur API terbaik, tetapi Rust bertabrakan dengan proses itu
Meski sistem tipe Rust lebih kuat, dengan Swift pun kita bisa memperoleh 90% performanya dan alurnya terasa jauh lebih alami
Tidak adanya namespace di crates.io mungkin adalah kritik terbesar
Siapa pun bisa mengambil lebih dulu nama paket umum di ruang global, dan kecuali menghindari repositori crates.io, kebanyakan orang harus menerimanya. Padahal sebagian paket dengan nama umum yang sudah diambil seperti itu bukanlah paket terbaik untuk dipakai
Mungkin ini reaksi balik terhadap notasi reverse DNS ala Java yang panjang dan menyebalkan, tetapi pendekatan seperti GitHub—menambahkan namespace pengguna/grup di depan nama paket—sepertinya akan menjadi jalan tengah yang baik
Saya mengirim analisis itu ke tim crates.io dan juga menunjukkan adanya kebijakan yang melarang otomasi, tetapi mereka menjawab bahwa itu belum menjadi bukti yang cukup bahwa ada penyerobotan nama
Masalah crates.io adalah meski punya kebijakan yang jelas, kebijakan itu tidak ditegakkan. Jadi nama crate yang pendek dan mudah diingat sudah habis diambil, dan tidak ada cara untuk mendapatkannya kembali
NPM, PyPI, RubyGems, Hex dari Elixir, Cabal dari Haskell, dan lainnya—sekitar 2014–2015 saat Rust muncul, saya sulit mengingat package manager non-Java yang bukan memakai satu namespace global
Sebagian kemudian mencoba memperbaikinya, tetapi saat itu memang era ketika package manager bekerja seperti itu
Sistem manajemen dependensi yang lebih buruk dari bahasa-bahasa lain setelahnya hampir tidak belajar dari contoh sebelumnya
Keuntungannya, bahasa tidak lagi membutuhkan database paket global. Jika Anda menaruh paket di example.com/your-thing, itu praktis langsung menjadi rilis
Tentu saja, cache dan mesin pencari bisa disediakan terpisah jika diinginkan
Contohnya, http-server buruk jadi jangan dipakai, pakailah MuffinTop; hal semacam itu harus diketahui begitu saja
Konsep nama paket yang tersertifikasi menarik, tetapi jika seiring waktu kode di balik alias berubah, dalam praktiknya kemungkinan akan membingungkan
Pada akhirnya, sepertinya ini akan tetap menjadi bagian dari proses menjadi pakar domain di ekosistem mana pun
Jika membuat
.cargo/config.tomldi root workspace, itu berlaku untuk semua crate, sehingga bisa mengatur lint Clippy globalDi dalam file, cukup masukkan sesuatu seperti
rustflags = ["-Wclippy::lint_name_to_warn", "-Dclippy::lint_name_to_deny"]di bawah[build]Namun,
rustflagsbersifat menimpa, bukan menambahkan, jadi jika ada sumber lain seperti variabel lingkunganRUSTFLAGS, sumber itu akan menimpa pengaturan inilib.rsataumain.rs. SederhanaSaya belajar Rust karena tampaknya jelas akan menjadi penting secara profesional. Saya benar-benar ingin menyukainya dan bisa melihat kelebihannya, tetapi sejauh ini Rust termasuk salah satu bahasa paling tidak menyenangkan yang pernah saya pakai
Saya terus berharap rasa tidak suka itu akan hilang seiring meningkatnya kemahiran, tetapi makin saya menaiki kurva belajarnya, tetap saja tidak terasa makin sayang
Tidak apa-apa. Ini mungkin bukan satu-satunya bahasa yang saya benci meski bisa memakainya dengan mahir. Hanya saja, begitu banyak orang bilang mereka mencintai Rust sehingga saya kira saya juga akan menikmatinya
Kompiler Rust juga tampaknya makin baik dalam menerima lebih banyak kasus yang valid
Kunci memahami borrow checker adalah memahami model memori yang mendasarinya. Model memori Rust sama dengan C, kecuali perluasan untuk abstraksi seperti generic
Aturan borrow checker awalnya tampak sewenang-wenang, tetapi sangat terkait dengan model memori ini. Saat tanpa sengaja tersandung borrow checker, justru di situlah nilainya, karena itu berarti bug yang dibuat akibat kurang fokus
Yang menakutkan adalah bahasa seperti C atau C++ bisa saja menerima kode semacam itu begitu saja dan lanjut
Sistem tipe Rust yang ketat dan borrow checker-nya mendorong dengan halus agar kode distrukturkan dengan benar, dan saya yakin itu memperbaiki desain kode saya di semua bahasa yang saya pakai
Itu fitur usability programmer yang sangat mendasar dan dimiliki sebagian besar bahasa populer, bahkan C++ sudah lama punya argumen default
Saya mantan programmer C/C++ yang selama 10 tahun hampir tiap minggu memanggil pthread, dan sekarang saya memakai Rust async di mana-mana
Saya tidak tahu kenapa async begitu dibenci. Menurut saya semua orang seharusnya memakai async untuk semua hal. Termasuk pekerjaan “sederhana” yang dari luar terlihat single-threaded
Kalau use case penulisnya Wasm, pasti perspektifnya akan berbeda
Pekerjaan yang memakai buffer besar atau menggunakannya kembali untuk menghindari biaya alokasi sering kali juga diuntungkan oleh thread pool gaya lama. Bump allocator atau sharded allocator bisa menyelesaikan sebagian, tetapi untuk loop ketat yang bisa divektorisasi dan CPU-bound, thread pool bekerja lebih baik
Async adalah alat yang bagus, tetapi bukan berarti selalu konteks yang optimal
Go, C#, TypeScript tidak punya hambatan seperti itu
Misalnya, tanpa decorator yang diimpor dari Tokio, sepertinya kita bahkan tidak bisa memakai
awaitdi dalam fungsimainEnginebukanSend, tetapi saya mencoba memakainya di dalam closure asyncGPT-4 menyarankan membuat
tokio Runtimedi dalam thread dan memakaiblock_on(). Saya akan mencobanya besok. Ini proyek Rust serius pertama sayaSaya juga penasaran apakah “sekarang memakai Rust async di mana-mana” berarti “memakai Tokio di mana-mana”
Pemrograman Rust benar-benar berbeda dari hubungan yang abusif. Kompiler berusaha membantu semaksimal mungkin, dan khususnya pesan error rustc termasuk yang terbaik di dunia
Yang lebih mirip hubungan abusif bukan kompiler Rust, melainkan sistem operasinya. Hardware juga sama, karena assembly harus dijalankan dengan benar; kalau dilihat begitu, itu juga bisa disebut hubungan abusif
Pesan error Rust tak tertandingi, tidak ada kompiler lain yang mendekati
Sebagai tambahan, saya baru-baru ini memakai LaTeX dan pesan error-nya mengerikan. Proses menatap error untuk memahami apa yang salah benar-benar seperti mimpi buruk
Futuretidak lagiSenddanSyncdi semua titik pemanggilan rekursifSeluruh konsol tertutup error, dan error sintaks sebenarnya terkubur di suatu tempat di tengahnya
Keluhan utama saya adalah masih belum sepenuhnya memahami lifetime, dan kompiler juga tidak selalu bisa membantu. Saya mengerti alasannya, karena kompiler mengambil keputusan secara konservatif
Dalam pengujian C++, orang sering berkata “kalau sudah bisa dikompilasi, umumnya sudah benar”
Jika Anda berpikir Rust menangani begitu banyak kesalahan sehingga kasus pengujian yang umum menjadi tidak bermakna, itu menurut saya tanda bahwa di bahasa lain Anda tidak menguji hal yang benar
Yang perlu diuji bukanlah masalah bahasa itu sendiri, melainkan logika bisnis
Jika saat melihat kode pengujian Anda merasa “kalau JavaScript, ini akan saya uji, tapi di Rust tidak perlu”, maka pengujian itu cukup dihapus saja
Tidak ada pemisahan “logika bisnis vs masalah bahasa”. Karena bahasa adalah fondasi tempat logika bisnis berada
Jika tidak menguji mode kegagalan, saya tidak tahu apa makna pengujian itu
Berbeda dari kebanyakan bahasa yang familier, C++ memiliki IFNDR, yang secara bercanda disebut false positive untuk pertanyaan “apakah ini program C++?”
Compiler C++ yang mengikuti standar dilarang memberi tahu dalam sebagian kasus ketika kode yang ditulis dicurigai tidak masuk akal, dan harus terus berjalan begitu saja lalu menghasilkan sesuatu
Itu bisa saja executable yang berjalan, atau executable yang menimbulkan bencana setiap hari Jumat. Tidak ada cara untuk mengetahuinya
Standar ISO memang mengidentifikasi kasus seperti ini, tetapi terlalu kabur sehingga sulit menangkap dengan tepat apa saja yang termasuk, dan dugaan saya sebagian besar software C++ non-trivial saat ini sebenarnya IFNDR. Lebih baik menolak seluruh bahasa itu saja
Rust tampaknya akhirnya meruntuhkan gagasan bahwa programmer harus sepenuhnya mengendalikan dan menyadari semua hal yang dilakukan compiler
Sebenarnya sejak puluhan tahun lalu pun sudah tidak demikian, dan compiler nyaris seperti sihir. Rust, lewat borrowing, banyak membalik arus itu, membuat orang lebih nyaman dengan kenyataan bahwa compiler lebih tahu daripada mereka
Saya berharap orang bisa menjadi lebih nyaman lagi. Kecuali memang diperlukan secara algoritmis, kita tidak semestinya harus secara eksplisit mengiterasi collection dari depan. Banyak operasi semestinya diparalelkan secara implisit. Saya ingin ada Bash yang bergaya Rust
Rust cukup transparan tentang apa yang dilakukannya, dan sangat konservatif terhadap sihir compiler. Bahasanya tidak melakukan alokasi heap, tidak melakukan reference counting, dan tidak ada konversi tipe numerik implisit
Tipe yang tidak dinyatakan dapat disalin secara implisit tidak akan disalin, dan bahkan itu pun hanya legal pada tipe yang bisa disalin dengan
memcpydangkal sederhanaRust memakai abstraksi tanpa biaya di banyak tempat, sehingga kita bisa memprediksi akan dikompilasi menjadi kode seperti apa, dan biasanya sederhana. Layout dasar tipe standar juga diketahui dengan baik, sehingga kita tahu iterasi
Vecakan dikompilasi menjadi loop yang menaikkan pointer, dan tidak ada paralelisme implisitMenggambarkan borrowing sebagai “compiler lebih tahu daripada programmer” itu aneh. Borrowing mirip dengan pemeriksaan tipe. Jika Anda mendeklarasikan suatu tipe sebagai sementara lalu mencoba memakainya seolah-olah berumur panjang, akan muncul error
Sama seperti fungsi yang dideklarasikan mengembalikan struct
Footetapi mengembalikanBarakan menghasilkan error. Alasan compiler “lebih tahu” hanyalah karena Anda menulis bugBorrowing juga dikompilasi menjadi penggunaan pointer langsung tanpa garbage collection, dan pada struct serta fungsi C ABI secara harfiah dijamin sama dengan pointer C. Jika Anda merasa lebih tahu daripada compiler, Anda juga bisa melewati lifetime dengan
unsafeiter()Namun saya tidak setuju bahwa itu harus implisit
Dalam beberapa hal, Rust memberi programmer lebih banyak kendali daripada C. Misalnya Rust mendukung inline assembly sebagai standar, sedangkan inline assembly di C bergantung pada ekstensi masing-masing vendor
Namun default yang nyaman memang sangat berbeda. Di Rust, type casting yang tidak aman menuntut banyak prosedur dan kehati-hatian, serta harus mengikuti lebih banyak aturan daripada C
Khususnya, reference di Rust pada dasarnya semuanya berperilaku seperti
restrict, dan ini sangat mudah dirusak ketika melakukan castingunsafedari raw pointer ke reference yang aman. Karena itu, jika ada pilihan, muncul insentif kuat untuk tidak menulis kode semacam ituJustru saya menginginkan kendali yang lebih eksplisit, dan ingin mengurangi bebannya dengan sistem tipe yang lebih ekspresif. Idealnya, sistem tipe Rust menjadi seperti varian Prolog
Belajar kapan harus berinvestasi pada batasan tipe dan kapan tidak adalah pelajaran penting
Ini bukan masalah khusus Rust, tetapi cara mengekspresikannya bisa sedikit berbeda
Saya pernah menangani C++ yang terlalu banyak tipe dan Java yang terlalu diabstraksikan serta terlalu banyak tipe, dan keduanya punya masalah refactoring yang sejenis
Sebaliknya, saya juga sering melihat Go yang kekurangan tipe dan dokumentasi, sehingga nilai-nilai tertentu tersebar ke mana-mana menjadi ranjau runtime, dan refactoring bisa menjadi sangat sulit
Rasa kemajuan di awal memang lebih cepat, tetapi biasanya Anda akhirnya mengirim bug kepada pengguna
Tidak ada jawaban ajaib untuk trade-off ini. Rust memberi pilihan yang cukup luas pada sumbu ini
Pernyataan bahwa “Rust berteriak sepanjang hari, setiap hari, tentang hal-hal yang dalam kehidupan lama dulu dianggap sepenuhnya normal” juga kurang lebih dilakukan oleh compiler C yang bagus jika semua flag diaktifkan
Saya suka bahasa dan compiler yang memungkinkan kita mematikan teriakan itu secara selektif dan sengaja menulis kode buruk. Kode buruk yang berjalan dan bisa ditulis cepat sering kali lebih baik daripada kode yang sempurna tetapi memakan waktu selamanya
Kita bisa membuat proof of concept yang buruk tetapi berjalan, lalu memperbaikinya agar tidak terlalu buruk
Poin bahwa “pengguna baru memang berhasil ditarik masuk, tetapi library atau tool tidak membaik secara dramatis, dan yang muncul hanya fork sekali pakai untuk menangani use case tertentu” tidak ada hubungannya dengan usia
Menarik core developer itu sulit, dan perlu banyak usaha agar hal itu menarik. Selain itu, konvensi budaya ditentukan oleh para adopter awal, dan tidak adanya konvensi sering kali sama merugikannya dengan konvensi yang buruk
Kalau melihat Python, akibat pendekatan yang longgar terhadap lingkungan pengembangan dan eksekusi, kini ada sekitar 50 cara yang saling bersaing untuk mengembangkan atau menjalankan program Python
Repositori paket yang paling banyak dipakai, PyPI, selama bertahun-tahun berantakan; sedikit orang yang membangun di atas paket yang sudah ada; namanya tampak seperti generator kata acak; ekosistemnya penuh malware; bahkan mencari paket dari command line pun tidak bisa
Ini bukan salah bahasanya, melainkan salah komunitas dan core team yang bersikap seperti penonton. Budaya lebih penting daripada teknologi yang ada di pusatnya
Saya tidak bermaksud hanya mengkritik Python; saya menyebutnya karena lebih memahami masalahnya. C sudah ada selama setengah abad, tetapi komunitasnya pun belum benar-benar merapikan bahkan setengah dari solusi yang sudah disediakan bahasa-bahasa yang lebih modern
Maksudnya situasi ketika compiler berteriak menyuruh kita memperbaiki sesuatu, tetapi kita hanya ingin menguji sebuah ide sebelum memolesnya sampai sempurna