Apa itu Crystal ?

Perkenalan Crystal sebagai bahasa terkompilasi dengan sintaks bergaya Ruby dan sistem tipe statis berinferensi.

Daftar isi

Crystal adalah bahasa pemrograman serbaguna yang mengompilasi kode sumber menjadi binary, yaitu berkas program yang siap dijalankan sistem operasi tanpa perantara. Bahasa ini mengadopsi sintaks bergaya Ruby dan menggunakan sistem tipe statis yang sebagian besar tipe disimpulkan otomatis oleh compiler. Topik ini memperkenalkan identitas Crystal melalui tiga program kecil: program sapaan yang menyerupai Ruby, program yang memperlihatkan inferensi tipe, dan program yang sengaja salah tipe untuk memperlihatkan error saat kompilasi. Ketiganya dijalankan langsung dari terminal, sehingga setiap pernyataan pada topik ini dapat diperiksa ulang.

Bahasa terkompilasi dengan sintaks Ruby#

Kode Crystal diproses compiler yang berbasis LLVM, yaitu infrastruktur kompilasi yang juga menjadi fondasi banyak bahasa lain. Compiler membaca berkas .cr, memeriksa seluruh tipe, lalu menghasilkan binary yang berjalan langsung di atas sistem operasi. Versi yang digunakan sepanjang jalur ini adalah 1.22.1 yang dirilis 22 Oktober 2026 dengan perbaikan keamanan TLS atas 1.22.0 dari 12 Oktober 2026. Sebelum keduanya, 1.21.0 yang dirilis 16 Juli 2026 mengaktifkan execution context secara bawaan, yakni mode pelaksanaan yang memungkinkan fiber dieksekusi pada beberapa thread.

Berkas binary hasil kompilasi tidak membutuhkan Crystal terpasang pada mesin tempat binary dijalankan. Kode sumber yang sama dapat dipindahkan dan dikompilasi ulang di mesin lain tanpa perubahan. Inilah perbedaan mendasar dengan bahasa yang menafsirkan kode baris demi baris: sebagian besar pekerjaan memahami program telah dilakukan lebih dulu oleh compiler, sehingga sisa waktunya digunakan untuk mengeksekusi.

Sintaks Crystal menyerupai Ruby pada banyak titik: metode didefinisikan dengan def, penamaan mengikuti gaya snake_case, dan teks dapat disisipkan dengan interpolasi #{...}. Gaya snake_case berlaku untuk metode dan variabel, sedangkan nama tipe menggunakan CamelCase. Program berikut memperlihatkan gaya itu sekaligus anotasi tipe yang tidak dimiliki Ruby.

crystal halo.cr
# Sapaan dengan union type: String atau Nil
def sapa(nama : String | Nil) : String
  if nama.nil?
    "Halo, tamu"
  else
    "Halo, #{nama}"
  end
end

puts sapa("Citra")
puts sapa(nil)
bash
# jalankan program lewat compiler
crystal run halo.cr
text Keluaran
Halo, Citra
Halo, tamu

Metode sapa menerima satu parameter bernama nama yang dianotasi String | Nil. Anotasi ini menyatakan union type, yakni tipe yang nilainya boleh berupa salah satu dari beberapa tipe yang dicantumkan, dalam hal ini String atau nil. Pernyataan if memilah kedua kemungkinan tersebut, sedangkan anotasi : String pada nilai balik menuntut kedua cabang mengembalikan String. Kode ini hampir sepenuhnya terbaca sebagai kode Ruby, tetapi compiler mengetahui tipe setiap nilai di dalamnya. Pengetahuan itulah yang membedakan Crystal dari Ruby: teks yang sama diperiksa ketat saat kompilasi tanpa mengubah gaya penulisannya.

Tipe statis dengan inferensi#

Tipe pada Crystal bersifat statis, artinya tipe setiap ekspresi diketahui compiler sebelum program dijalankan. Penulisan anotasi pada setiap variabel tidak diperlukan karena compiler menyimpulkan tipe dari ekspresi yang mengisinya, kemampuan yang disebut inferensi tipe (type inference). Pada Crystal, penyimpulan ini dilakukan untuk seluruh program sekaligus, bukan baris demi baris secara terpisah.

crystal inferensi.cr
harga = 15000
nama = "Kopi"

puts typeof(harga)
puts typeof(nama)
bash
# jalankan program inferensi
crystal run inferensi.cr
text Keluaran
Int32
String

Metode typeof mengembalikan nama tipe dari ekspresi yang diberikan. Variabel harga diisi literal bilangan bulat sehingga tersimpulkan sebagai Int32, sedangkan nama berisi teks dan tersimpulkan String. Tidak ada satu anotasi pun pada kedua baris penugasan itu, tetapi kedua tipe sudah pasti saat kompilasi. Anotasi menjadi diperlukan pada tempat yang tidak memiliki isi untuk disimpulkan, misalnya parameter metode seperti pada program sebelumnya.

Anotasi pada parameter metode, seperti nama : String | Nil pada program sebelumnya, tidak sekadar pelengkap. Compiler memakainya untuk memeriksa setiap pemanggilan metode tersebut di seluruh program, sehingga argumen yang salah tipe ditolak tanpa mengeksekusi satu baris pun. Anotasi juga menjadi dokumentasi yang selalu benar, karena compiler akan melaporkan error apabila isi metode tidak lagi cocok dengan anotasinya.

Error tipe tertangkap saat kompilasi#

Konsekuensi sistem tipe statis adalah kesalahan tipe tertangkap sebelum program berjalan. Program berikut memanggil duakali dengan argumen teks, padahal parameternya dianotasi Int32. Kode pada berkas ini lengkap dan sah secara sintaks, sehingga satu-satunya masalah adalah ketidakcocokan tipe argumennya.

crystal salah-tipe.cr
def duakali(x : Int32) : Int32
  x * 2
end

puts duakali("halo")
bash
# jalankan program yang sengaja salah tipe
crystal run salah-tipe.cr
text Keluaran
Showing last frame. Use --error-trace for full trace.

In salah-tipe.cr:5:14

 5 | puts duakali("halo")
                  ^
Error: expected argument #1 to 'duakali' to be Int32, not String

Overloads are:
 - duakali(x : Int32)

Compiler menolak melanjutkan dan mencetak pesan error sebelum satu baris pun program dieksekusi. Baris In salah-tipe.cr:5:14 menggunakan format berkas, baris, dan kolom, diikuti potongan kode yang bermasalah beserta tanda ^ pada posisi argumen yang ditolak. Bagian Overloads are mencantumkan definisi duakali yang tersedia sehingga penyebab ketidakcocokan terlihat langsung. Pada bahasa yang tipe diperiksanya saat runtime, kesalahan serupa baru muncul ketika baris itu benar-benar dijalankan, sedangkan Crystal menahannya di tahap kompilasi.

Baris pertama keluaran, Showing last frame. Use --error-trace for full trace., menandakan compiler hanya menampilkan satu lokasi yang paling relevan. Opsi --error-trace memuat jejak lengkap, yaitu seluruh rantai pemanggilan yang menyebabkan ketidakcocokan tipe, dan berguna ketika satu pesan berasal dari beberapa tempat. Untuk program kecil, tampilan ringkas seperti di atas biasanya sudah cukup untuk menemukan penyebabnya. Perintah run yang gagal juga ditandai dengan kode keluar bukan nol, sehingga skrip otomatisasi dapat mendeteksinya.

Ringkasan#

  • Crystal mengompilasi berkas .cr menjadi binary native melalui compiler berbasis LLVM, dan jalur ini menggunakan versi 1.22.1.
  • Sintaksnya menyerupai Ruby, tetapi Crystal bukan implementasi Ruby dan memiliki pustaka standar sendiri.
  • Tipe bersifat statis dan disimpulkan otomatis dari pengisian nilai, sehingga program pendek dapat ditulis tanpa anotasi.
  • Kesalahan tipe ditolak saat kompilasi dengan pesan yang memuat lokasi berkas, baris, kolom, dan kandidat overload.

Referensi#