Pilar Interop

Interop C++ dua arah sebagai syarat mutlak desain Carbon dan alasannya.

Daftar isi

Topik ini membahas pilar desain pertama Carbon, yaitu interoperabilitas dua arah dengan C++ yang diperlakukan sebagai syarat mutlak, bukan sekadar fitur pelengkap. Setelah membacanya, alasan di balik posisi sentral interop dalam desain bahasa, mekanisme yang direncanakan untuk mewujudkannya, dan batasan yang diakui secara resmi oleh dokumen desain dapat diuraikan dengan jelas. Seluruh pembahasan bertumpu pada dokumen primer proyek karena lapisan interop yang utuh belum dapat dicoba pada perangkat bantu yang tersedia hari ini.

Mandat bahasa penerus di balik interop#

README proyek Carbon memperkenalkan proyek ini sebagai bahasa penerus C++ yang bersifat eksperimental, dan menempatkan performa yang setara dengan C++ serta interop dua arah yang mulus dengan C++ sebagai dua syarat utama sebuah bahasa penerus. Interop adalah bentuk ringkas dari interoperability, yakni kemampuan dua bahasa untuk saling memanggil kode satu sama lain dalam satu program. Rumusan syaratnya bersifat tegas, sehingga sebuah library di bagian mana pun dari tumpukan perangkat lunak C++ dapat mengadopsi Carbon tanpa memindahkan sisanya. Klaim inilah yang mengangkat interop dari daftar fitur biasa menjadi fondasi seluruh desain.

Dokumen filosofi interop menjelaskan konsekuensi dari klaim tersebut. Carbon tidak memperlakukan C++ sebagai entitas asing yang dijangkau lewat antarmuka fungsi asing, melainkan merancang model semantiknya bersama dengan C++, sehingga template, hierarki kelas, dan aturan pemilihan overload C++ dapat dipahami dengan fidelitas tinggi. Lapisan interop dirancang bekerja pada tingkat analisis semantik, dan bukan hanya pada tingkat penautan berkas objek. Konsekuensinya, kompiler Carbon dituntut mengerti C++ sedalam kompiler C++ itu sendiri, dan tuntutan tersebut menjadi salah satu alasan proyek ini bergerak bertahap.

Kedua arah dalam satu lapisan semantik#

Dokumen desain bahasa mendefinisikan interop sebagai kemampuan memanggil kode C dan C++ dari kode Carbon dan sebaliknya, dengan dua tujuan yang saling menopang, yaitu berbagi ekosistem kode dan library dengan C++, serta membuka jalan migrasi inkremental ke Carbon. Desain interop Carbon bertumpu pada tiga hal. Pertama, cakupan interop mencakup beragam bentuk kode, mulai dari kelas, struct, hingga template, dan bukan hanya fungsi bebas. Kedua, desain bersedia mengekspos idiom C++ ke dalam kode Carbon dan sebaliknya apabila hal itu diperlukan demi performa maksimal lapisan interop. Ketiga, wrapper dan pemrograman generik digunakan untuk meminimalkan atau meniadakan overhead saat program berjalan.

Pada arah masuk, header C++ diimpor dengan deklarasi khusus, dan seluruh nama hasil impor ditempatkan di dalam package bernama Cpp sehingga asal setiap simbol selalu terlihat. Bentuk deklarasinya pada dokumen desain tampak seperti berikut.

carbon Contoh: mengimpor header C++ menurut desain
// tidak-dijalankan
import Cpp library "circle.h";

Nama pada namespace C++ seperti shapes dapat diakses sebagai Cpp.shapes dari sisi Carbon. Pada arah sebaliknya, sebuah package Carbon dapat mengekspor berkas header untuk disertakan dari kode C++, sehingga fungsi dan tipe Carbon dapat dipanggil dari C++. Filosofi yang mendasari kedua arah itu sama, yaitu overhead nol, yang dalam praktiknya berarti konversi tanpa salinan data untuk tipe primitif dan tipe kosakata non-pemilik seperti pointer dan reference. Diagram berikut merangkum kedua arah panggilan tersebut di dalam satu aplikasi.

Kode C++library yang sudah adaKode Carbonlibrary yang baru ditulisC++ memanggil API CarbonCarbon memanggil API C++model memori yang sama, tanpa salinan data
Dua arah panggilan antara C++ dan Carbon dalam satu aplikasi

Pemetaan tipe dirancang agar tidak mengejutkan pembaca. Tipe bilangan bulat berukuran tetap seperti i32 dinyatakan setara dengan int32_t dari C++, tipe bool dan f64 dipetakan langsung, sedangkan std::string_view dari C++ direncanakan setara dengan str dari Carbon pada tingkat ABI untuk target 64-bit dengan tata letak memori yang cocok. Warisan (inheritance) juga termasuk dalam rencana, yaitu kelas Carbon dapat mewarisi kelas C++ dan sebaliknya, bahkan untuk metode virtual, karena representasi datanya dibuat konsisten.

Kompromi yang diakui secara terbuka#

Desain interop Carbon tidak menjanjikan kesetaraan penuh, dan kejujuran tentang batasan ini justru menjadi bagian dari desainnya. Hanya sebagian API Carbon yang terlihat dari C++ dan hanya sebagian API C++ yang terlihat dari Carbon. Fitur C++ yang jarang digunakan dan rumit, misalnya pewarisan ganda, mendapat batasan. Fitur C++ yang membebani performa kode yang tidak menggunakannya, seperti RTTI dan exception, secara khusus dinyatakan akan ditinjau ulang di Carbon. Dokumen filosofi dan tujuan interop juga mencantumkan daftar non-tujuan yang panjang, di antaranya dukungan exception C++ tanpa kode jembatan, metaprogramming lintas bahasa, konversi seluruh tipe C++ menjadi tipe Carbon, dan kesetaraan penuh antara toolchain Carbon murni dengan toolchain campuran.

AspekYang dijanjikan desainBatasan yang diakui
Cakupan APImayoritas fungsi dan tipe C++ dapat digunakan tanpa kode jembatanhanya subset API yang saling terlihat
Fitur C++ lanjutantemplate, overload, atribut, dan ADL (argument-dependent lookup) didukungpewarisan ganda dibatasi dan pola CRTP perlu kode jembatan atau penulisan ulang
Model ABIdukungan penuh untuk C ABI dan ekspor header C++ABI stabil untuk seluruh bahasa dinyatakan sebagai non-tujuan

Pernyataan non-tujuan ABI layak dibaca cermat. Carbon tidak akan memiliki ABI yang stabil untuk bahasa dan library-nya secara keseluruhan, dan sebagian besar fitur bahasa dirancang tanpa stabilitas ABI. Sebagai gantinya, fitur bahasa yang tahan perubahan ABI direncanakan bersifat opt-in dan eksplisit. Sementara itu, kode C++ yang sudah terkompilasi tetap dapat digunakan, tetapi dokumen desain memperkirakan bahwa kompilasi ulang kode C++ dengan toolchain Carbon akan memberikan hasil yang paling lengkap, baik dari sisi kenyamanan maupun performa.

Ringkasan#

  • Interop dua arah dengan C++ adalah syarat mutlak desain Carbon, karena klaim bahasa penerus menuntut satu library di tengah tumpukan C++ dapat menjadi Carbon tanpa memindahkan sisanya.
  • Desainnya bekerja pada tingkat semantik, dengan package Cpp sebagai wadah simbol impor, pemetaan tipe yang tidak mengejutkan, serta dukungan untuk fitur C++ lanjutan seperti template dan overload.
  • Filosofi utamanya adalah overhead nol, yaitu model memori yang digunakan bersama, konversi tanpa salinan, dan kode jembatan yang diminimalkan lewat wrapper serta pemrograman generik.
  • Desain mengakui batasannya secara resmi, antara lain subset API yang saling terlihat, batasan pewarisan ganda, peninjauan ulang exception, dan ketiadaan ABI stabil untuk seluruh bahasa.

Referensi#