Daftar Isi
- Binding - Membuat Variabel
- Penamaan Variabel
- Rebinding - Memperbarui Nilai Variabel
- Manajemen Memori di Elixir
- Referensi
Di Elixir, data bersifat tetap, setelah dibuat nilainya tidak bisa diubah. Jika kita menulis ulang sebuah variabel, Elixir tidak mengganti nilai lama, tetapi membuat nilai baru dan mengaitkan nama yang sama ke nilai tersebut. Cara kerja ini disebut immutability. Dalam pelajaran ini kita akan mempelajari bagaimana immutability diterapkan melalui binding, cara menamai variabel dengan benar, konsep rebinding, serta bagaimana garbage collector di BEAM mengelola memori agar program tetap efisien dan berjalan lancar.
Binding - Membuat Variabel
Membuat variable di Elixir sekilas tampak mirip dengan bahasa pemrograman imperatif seperti Ruby atau Python, tetapi cara Elixir memperlakukan nilai berbeda secara mendasar.
Di Bahasa Imperatif - Kotak yang Dapat Diisi Ulang
Dalam bahasa seperti Ruby, variable bersifat mutable (dapat diubah):
irb(main):001:0> monthly_salary = 5_000_000
=> 5000000
irb(main):002:0> monthly_salary = 6_000_000
=> 6000000
Kita dapat membayangkan variable monthly_salary sebagai kotak bernama.
Pertama, kotak itu diisi dengan nilai 5_000_000. Ketika nilainya diperbarui menjadi 6_000_000, isi kotak yang sama diganti. Kotaknya tetap sama, tetapi isinya berubah.
Sifat ini disebut mutable, artinya data dapat dimodifikasi setelah dibuat.
Secara teknis, variable dalam bahasa imperatif menunjuk ke lokasi memori tetap, dan nilai di lokasi tersebut dapat diganti kapan saja. Perubahan ini dianggap sebagai “pembaruan nilai”.
Di Elixir - Kotak Tersegel
Sekilas, sintaks pembuatan variable di Elixir terlihat serupa:
iex> monthly_salary = 5_000_000
5000000
Namun konsep di baliknya sangat berbeda.
Kita dapat membayangkan nilai 5_000_000 ditempatkan di dalam kotak tersegel, lalu diberi label monthly_salary. Karena kotaknya tersegel, isinya tidak dapat diubah. Sifat ini disebut immutable.
Jika kita menulis ulang monthly_salary dengan nilai baru:
iex> monthly_salary = 6_000_000
6000000
Elixir tidak membuka kotak lama dan mengganti isinya. Ia membuat kotak baru yang berisi 6_000_000, lalu memindahkan label nama monthly_salary ke kotak baru tersebut. Kotak lama tetap ada hingga sistem garbage collector menghapusnya ketika sudah tidak digunakan.
Binding di Elixir bukan hubungan antara nama dan lokasi memori yang bisa dimodifikasi, melainkan antara nama dan nilai. Nama hanyalah label yang menunjuk pada suatu nilai, bukan wadah yang menyimpannya.
Kita dapat mengamati perilaku ini langsung di IEx:
iex> monthly_salary = 5_000_000
5000000
iex> monthly_salary
5000000
iex> monthly_salary * 12
60000000
Nilai aslinya tetap sama. Ketika kita melakukan binding baru untuk monthly_salary, Elixir tidak mengubah nilai lama, melainkan membentuk asosiasi baru antara nama dan nilai yang baru.
Tipe Data Ditentukan Otomatis
Elixir adalah bahasa dinamis, artinya tipe data ditentukan otomatis berdasarkan nilai yang diberikan:
name = "Alice" # string
age = 30 # integer
height = 1.72 # float
Kita tidak perlu menentukan tipe data secara eksplisit karena runtime Elixir mengenali tipe setiap nilai secara otomatis. Pendekatan ini membuat kode lebih ringkas dan fleksibel tanpa mengorbankan kejelasan logika.
Penamaan Variabel
Penamaan variable di Elixir mengikuti aturan sederhana namun penting untuk menjaga kejelasan kode. Nama harus diawali dengan huruf kecil (a-z) atau garis bawah (_). Setelah karakter pertama, kita dapat menambahkan huruf, angka (0-9), atau garis bawah tambahan. Garis bawah biasanya digunakan untuk memisahkan kata dalam nama variable sebagai pengganti spasi.
# Contoh nama variable valid
valid_variable_name
also_valid_1
validButNotRecommended
Huruf kapital di awal tidak diperbolehkan untuk nama variable:
# Contoh tidak valid
VariableName # error: huruf kapital di awal
Dalam Elixir, huruf kapital di awal nama digunakan secara khusus untuk module (misalnya String, Map, List).
Perbedaan gaya ini memudahkan kita membedakan apakah suatu nama merujuk pada module atau variable hanya dengan melihatnya sekilas.
Akhiran Tanda Tanya dan Tanda Seru
Elixir mengizinkan penggunaan tanda tanya (?) dan tanda seru (!) di akhir nama variable.
Kedua tanda ini tidak memengaruhi perilaku kode secara teknis, tetapi merupakan konvensi idiomatik yang membantu pembaca memahami maksud kode dengan cepat.
-
Tanda tanya (
?) menunjukkan bahwa nilai bersifat logis atau menghasilkan boolean. Nama sepertivalid?,empty?, atauactive?biasanya menandakan pertanyaan yang dapat dijawab "ya" atau "tidak". -
Tanda seru (
!) menandai nilai atau operasi penting, tegas, atau berpotensi berisiko. Dalam konteks variable, tanda ini sering digunakan untuk menandakan bahwa nilai tersebut sudah diverifikasi atau dijamin ada. Contohnya,important_data!dapat berarti “nilai ini pasti tersedia dan aman digunakan”.
Contoh penggunaannya:
user_valid? = true
important_data! = "Nilai ini dijamin tersedia"
Meskipun konvensi ini tidak wajib, penamaan yang konsisten membuat kode jauh lebih mudah dibaca dan dipahami, baik oleh diri sendiri maupun orang lain di masa depan.
Rebinding - Memperbarui Nilai Variabel
Semua data di Elixir bersifat immutable, artinya nilai yang sudah dibuat tidak dapat diubah. Jadi, ketika kita menulis ulang sebuah variable seperti ini:
monthly_salary = 6_000_000
yang terjadi bukan penggantian isi nilai lama, melainkan pembuatan nilai baru dan pengaitan ulang nama monthly_salary ke nilai tersebut.
Proses ini disebut rebinding.
Secara konseptual, rebinding adalah cara Elixir mempertahankan fleksibilitas tanpa melanggar prinsip immutability.
Kita tetap dapat "memperbarui" variable, tetapi yang berubah hanyalah hubungan antara nama dan nilai, bukan isi nilai itu sendiri. Nilai lama tetap ada di memori hingga garbage collector menghapusnya secara otomatis.
Contoh rebinding di IEx:
iex> monthly_salary = 5_000_000 ❶
5000000
iex> monthly_salary ❷
5000000
iex> monthly_salary = 5_123_000 ❸
5123000
iex> monthly_salary ❹
5123000
Penjelasannya:
- ❶ Nama
monthly_salarypertama kali di-bind ke nilai5_000_000. - ❷ Saat diperiksa, nama tersebut mengacu pada nilai
5000000. - ❸ Nama
monthly_salarykemudian di-rebind ke nilai baru5_123_000. - ❹ Kini
monthly_salarymengacu pada nilai baru5123000.
Setiap kali kita melakukan rebinding, BEAM (mesin virtual yang menjalankan Elixir) tidak mengubah nilai lama di memori. Ia membuat alokasi baru untuk nilai baru dan memperbarui referensi nama ke sana. Jika tidak ada referensi yang tersisa ke nilai lama, BEAM akan menghapusnya melalui mekanisme garbage collection.
Manajemen Memori di Elixir
Elixir menggunakan garbage collector (GC) yang terintegrasi di dalam runtime BEAM untuk mengelola memori secara otomatis.
Tugas utama GC adalah mendeteksi data yang sudah tidak lagi digunakan dan membebaskan ruang memori yang ditempati data tersebut.
Kita dapat melihat peran GC ketika melakukan rebinding:
iex> monthly_salary = 5_000_000
5000000
iex> monthly_salary = 6_000_000
6000000
Setelah baris kedua dijalankan, nama monthly_salary tidak lagi mengacu pada nilai 5_000_000, melainkan pada nilai baru 6_000_000. Karena tidak ada referensi lain yang menunjuk ke nilai lama, BEAM menandainya sebagai data yang tidak dibutuhkan lagi. Garbage collector kemudian membebaskan memori yang digunakan nilai tersebut agar dapat dipakai ulang oleh sistem.
Yang membuat BEAM istimewa adalah cara kerjanya yang berbasis proses.
Setiap proses Elixir memiliki ruang memori sendiri (heap) dan garbage collector-nya sendiri. Dengan demikian, setiap proses menjalankan manajemen memorinya secara independen. Ketika satu proses melakukan garbage collection, proses lain tetap berjalan tanpa terhenti, sehingga sistem secara keseluruhan tetap responsif.
Pendekatan ini memberikan dua keuntungan utama:
- Efisiensi dan prediktabilitas: setiap proses hanya mengelola memorinya sendiri, sehingga siklus garbage collection berlangsung cepat dan terukur.
- Stabilitas sistem: masalah pada satu proses tidak memengaruhi proses lain, membuat sistem tetap berjalan bahkan di bawah beban tinggi.
Semua ini berlangsung otomatis di belakang layar, kita tidak perlu mengatur alokasi atau pembebasan memori secara manual seperti pada bahasa C atau C++.
Elixir dan BEAM menangani seluruh siklus hidup data secara mandiri, memungkinkan kita fokus pada logika program tanpa khawatir terhadap kebocoran memori atau pengelolaan sumber daya yang rumit.
Arsitektur per-process garbage collection inilah yang membuat sistem berbasis Elixir dapat berjalan terus-menerus selama bertahun-tahun tanpa perlu dimatikan atau restart.
Referensi
- Jurić, S. (2024). Elixir in Action (3rd ed.). Manning Publications.
Top comments (0)