- Tim TypeScript memilih untuk melakukan porting ke Go daripada penulisan ulang total agar pesan kesalahan dan semantik tetap identik.
- Pengumpulan sampah (garbage collection) dan closure kelas satu (first-class closures) pada Go sangat penting untuk menangani struktur data kompleks yang dihasilkan oleh compiler.
- Pemeriksa peminjaman (borrow checker) Rust akan memaksa penggunaan solusi manual untuk referensi melingkar, yang menambah kompleksitas yang tidak perlu.
- Go menyediakan pembuatan kode asli yang matang dan konkurensi memori bersama tanpa upaya tambahan apa pun.

Ketika tim TypeScript memutuskan untuk memindahkan kompiler mereka ke bahasa baru, mereka memiliki tujuan yang jelas: menjaga agar semuanya berfungsi persis seperti sebelumnya. Itu berarti mempertahankan pesan kesalahan dan semantik yang telah diandalkan pengembang selama bertahun-tahun. Menurut Anders Hejlsberg, arsitek utama, penulisan ulang penuh tidak mungkin dilakukan karena akan berisiko merusak kompatibilitas mundur. Sebagai gantinya, mereka memilih porting—dan keputusan itu membuka jalan bagi pilihan yang mengejutkan: Menggantikan Rust.
Porting ini membutuhkan bahasa yang mampu menangani struktur internal kompilator yang rumit tanpa memaksa perubahan besar. Tim dengan cepat menyadari bahwa pengumpulan sampah (garbage collection) dan penutupan kelas satu (first-class closures) adalah hal yang mutlak. Go menawarkan keduanya secara langsung, bersama dengan pembuatan kode asli yang matang dan konkurensi memori bersama di setiap platform utama. Rust, di sisi lain, akan membutuhkan solusi manual yang signifikan, terutama untuk struktur data melingkar kompilator.
Mengapa Harus Mengganti Rust dengan Port?
Hejlsberg menjelaskan bahwa kompiler penuh dengan pointer induk, tipe rekursif, dan simbol yang saling merujuk. Hal ini menciptakan referensi melingkar yang wajar dalam bahasa dengan pengumpulan sampah (garbage collection). Runtime Go menangani hal ini dengan mulus, memungkinkan tim untuk fokus pada porting daripada berjuang melawan bahasa tersebut. Pemeriksa peminjaman (borrow checker) Rust, meskipun ampuh untuk keamanan memori, sama sekali tidak memungkinkan bentuk tersebut tanpa menggunakan kode tidak aman (unsafe code) atau trik penghitungan referensi. Itu akan menambah kompleksitas dan risiko, tanpa imbalan yang jelas.
Saat membandingkan kedua bahasa tersebut, tim tidak menemukan keunggulan signifikan dalam pembuatan kode atau konkurensi untuk Rust. Pembuatan kode asli Go sudah matang, dan goroutine-nya menyediakan model yang sederhana dan efektif untuk eksekusi konkuren. Performa Rust mungkin sedikit lebih baik dalam beberapa kasus khusus, tetapi upaya ekstra yang diperlukan untuk membuat kompiler bekerja dengan aturan kepemilikannya tidak dapat dibenarkan. Porting harus pragmatis, bukan sekadar pameran fitur bahasa.
Kompatibilitas dan Semantik: Prioritas Utama
Alasan utama di balik porting ini adalah untuk mempertahankan perilaku yang identik. Pengembang bergantung pada pesan kesalahan TypeScript untuk men-debug kode mereka, dan setiap perubahan dapat merusak alur kerja mereka. Dengan melakukan porting ke Go, tim dapat menggunakan kembali logika dan struktur data yang ada, memastikan bahwa output tetap kompatibel byte demi byte. Pendekatan ini juga mengurangi risiko munculnya bug halus yang mungkin ditimbulkan oleh penulisan ulang.
Pengumpulan sampah (garbage collection) Go merupakan kunci keberhasilan. Grafik internal node dan referensi kompiler sangat saling terkait, dan manajemen memori manual akan menjadi mimpi buruk. Dengan Go, tim dapat mengalokasikan dan membebaskan memori secara otomatis, sehingga mereka dapat fokus pada logika kompiler. Closure kelas satu juga mempermudah implementasi berbagai tahapan dan transformasi yang dilakukan kompiler, karena dapat menangkap konteks secara alami.
Pemeriksa Peminjaman Rust: Sebuah Hal yang Menjadi Penghalang Kesepakatan
Pemeriksa peminjaman (borrow checker) Rust dirancang untuk mencegah kondisi race data dan kesalahan memori pada waktu kompilasi, tetapi memiliki aturan yang ketat. Struktur data kompiler TypeScript penuh dengan siklus dan referensi bersama, yang ditolak oleh pemeriksa peminjaman kecuali Anda menggunakan blok tidak aman (unsafe blocks) atau Rc/RefCell. Hejlsberg mencatat bahwa ini akan memaksa solusi manual untuk setiap struktur data melingkar, menambah kode berulang (boilerplate) dan membuat kode lebih sulit dipelihara. Tidak ada keuntungan pembuatan kode (codegen) atau konkurensi yang dapat membenarkan pekerjaan tambahan tersebut.
Pada akhirnya, pilihannya jelas. Go menawarkan keseimbangan yang tepat antara kesederhanaan, kinerja, dan kompatibilitas. Proses porting sedang berlangsung, dan tim yakin bahwa ini akan memberikan pengalaman TypeScript yang sama dengan kompiler yang lebih cepat dan efisien. Bagi pengembang, ini berarti tidak ada kejutan—hanya alat andal yang selalu mereka gunakan, berjalan di atas fondasi yang lebih modern.
Setelah mempertimbangkan semuanya, keputusan untuk memilih Go daripada Rust untuk port TypeScript didasarkan pada pertimbangan rekayasa praktis. Kebutuhan akan pengumpulan sampah (garbage collection), penutupan kelas satu (first-class closures), dan penanganan referensi melingkar yang mulus menjadikan Go pilihan yang tepat. Jaminan keamanan Rust memang mengesankan, tetapi hal itu datang dengan biaya yang tidak ingin ditanggung oleh tim TypeScript. Hasilnya adalah port yang mempertahankan semua hal yang disukai pengembang tentang TypeScript sekaligus meletakkan dasar untuk peningkatan di masa mendatang.