DEV Community

Cover image for Variabel, Imutabilitas, dan Garbage Collection
Muzhawir Amri
Muzhawir Amri

Posted on • Edited on • Originally published at muzhawir.com

Variabel, Imutabilitas, dan Garbage Collection

Daftar Isi

Binding - Membuat Variabel

Di Elixir, kita bisa memberi nama untuk menyimpan sebuah nilai, mirip seperti membuat variabel di bahasa pemrograman lain. Namun, konsep “variabel” di Elixir berbeda secara mendasar dari variabel di bahasa imperatif seperti Python atau JavaScript.

Yang sebenarnya kita lakukan di Elixir bukan menyimpan nilai dalam wadah yang bisa berubah, melainkan mengikat sebuah nama ke suatu nilai tertentu. Proses ini disebut binding.

Di Bahasa Imperatif: Kotak yang Bisa Diisi Ulang

Mari kita lihat bagaimana variabel bekerja di bahasa seperti Python:

>>> monthly_salary = 5_000_000

>>> monthly_salary = 6_000_000
Enter fullscreen mode Exit fullscreen mode

Di sini, kita bisa membayangkan variabel monthly_salary sebagai sebuah kotak bernama. Pertama, kotak itu diisi dengan angka 5_000_000. Kemudian, kita membuka kembali kotak yang sama dan mengganti isinya dengan angka 6_000_000.

Kotaknya tetap satu, tapi isinya berubah. Inilah yang disebut mutable, artinya data bisa dimodifikasi setelah dibuat. Pendekatan ini umum digunakan dalam bahasa imperatif, karena program ditulis sebagai serangkaian perintah yang mengubah keadaan (state).

Di Elixir: Kotak Tersegel

Sekarang bandingkan dengan Elixir. Ketika kita menulis:

iex> monthly_salary = 5_000_000
Enter fullscreen mode Exit fullscreen mode

Secara tampilan, ini memang mirip dengan Python. Tapi secara konsep, Elixir bekerja dengan cara yang berbeda. Di sini, kita membuat sebuah nilai 5_000_000, lalu mengikat nama monthly_salary ke nilai tersebut. Proses ini disebut binding.

Untuk membayangkannya, kita bisa tetap menggunakan analogi kotak. Nilai 5_000_000 kita masukkan ke dalam sebuah kotak, lalu kotak tersebut langsung disegel. Setelah itu, kita tempelkan label bernama monthly_salary ke kotak tersebut. Karena kotaknya tersegel, isinya tidak bisa diubah. Inilah yang dimaksud dengan sifat immutable.

Kita bisa menggunakan nama monthly_salary dalam berbagai ekspresi:

iex> monthly_salary = 5_000_000
5000000

iex> monthly_salary
5000000

iex> monthly_salary * 12
60000000
Enter fullscreen mode Exit fullscreen mode

Nilai 5_000_000 tetap tersimpan dan tidak berubah. Tapi apa yang terjadi jika kita menulis ulang seperti ini:

iex> monthly_salary = 6_000_000
Enter fullscreen mode Exit fullscreen mode

Sekilas, ekspresi tersebut terlihat seperti kita sedang mengganti isi variabel. Namun, yang sebenarnya terjadi tidak demikian. Kita tidak membuka kotak lama dan mengganti isinya, karena kotak tersebut sudah tersegel dan tidak bisa diubah lagi. Sebagai gantinya, Elixir membuat kotak baru berisi 6_000_000, lalu memindahkan label monthly_salary ke kotak baru tersebut. Labelnya masih sama, tetapi sekarang menunjuk ke nilai yang berbeda.

Kotak lama tetap ada secara konseptual dan tidak terpengaruh. Selama masih dibutuhkan, nilainya tetap tersimpan di memori. Namun, jika tidak ada lagi nama yang merujuk ke sana, sistem akan menghapusnya secara otomatis melalui mekanisme garbage collection.

Dengan demikian, kita tidak benar-benar mengubah nilai di Elixir. Yang terjadi adalah pembentukan binding baru dengan nama yang sama. Nilai sebelumnya tetap ada secara konseptual, tetapi tidak lagi digunakan karena tidak ada nama yang menunjuk kepadanya.

Inilah salah satu prinsip utama dalam Elixir: semua nilai bersifat immutable, artinya tidak bisa diubah setelah dibuat. Sekali sebuah nilai ditempatkan ke dalam kotak, maka isinya akan tetap selama siklus hidupnya. Elixir tidak memiliki operasi untuk “mengubah nilai variabel” seperti yang biasa ditemui di bahasa imperatif. Yang tersedia hanyalah mekanisme untuk membuat binding baru yang menunjuk ke nilai lain.

Tipe Data Ditentukan Otomatis

Karena Elixir adalah bahasa pemrograman dinamis, tipe data akan dikenali secara otomatis berdasarkan nilai yang kita berikan:

name = "Alice"   # string
age = 30         # integer
height = 1.72    # float
Enter fullscreen mode Exit fullscreen mode

Penamaan Variabel

Nama variabel di Elixir harus diawali dengan huruf kecil (a sampai z) atau garis bawah (_). Setelah karakter pertama, kita bisa menambahkan huruf, angka (0 sampai 9), atau garis bawah tambahan. Garis bawah biasanya digunakan untuk memisahkan kata dalam nama dan menggantikan spasi:

# Contoh nama variabel yang valid:
valid_variable_name
also_valid_1
validButNotRecommended
Enter fullscreen mode Exit fullscreen mode

Huruf kapital di awal tidak diperbolehkan untuk nama variabel. Misalnya:

# Contoh tidak valid:
VariableName  # error: huruf kapital di awal
Enter fullscreen mode Exit fullscreen mode

Akhiran Tanda Tanya dan Tanda Seru

Elixir mengizinkan penggunaan tanda tanya (?) atau tanda seru (!) di akhir nama variabel. Penggunaan ini bersifat konvensional dan membantu memberi makna tambahan pada nama.

  • Tanda tanya (?) biasanya digunakan untuk menunjukkan bahwa nilai dalam variabel tersebut adalah hasil dari suatu kondisi logika, atau mewakili nilai boolean. Contohnya: valid?, empty?, atau active?.
  • Tanda seru (!) dalam nama variabel digunakan untuk memberi kesan bahwa nilai tersebut penting, telah melewati validasi, atau harus dijamin tersedia. Misalnya, kita bisa menggunakan data! untuk menandai bahwa nilai tersebut diambil dari function seperti File.read! yang akan menghasilkan error jika gagal. Ini murni gaya penamaan dan tidak memengaruhi perilaku program secara teknis.

Contoh:

user_valid? = true
processed_data! = File.read!("config.exs")
Enter fullscreen mode Exit fullscreen mode

Mengikuti konvensi penamaan seperti ini memang tidak diwajibkan, tetapi sangat dianjurkan. Nama variabel yang konsisten dan mudah dibaca akan sangat membantu dalam memahami dan memelihara kode, terutama ketika bekerja dalam tim atau dalam proyek jangka panjang.

Rebinding - Memperbarui Nilai Variabel

Kita telah melihat bahwa semua data di Elixir bersifat immutable, artinya nilainya tidak bisa diubah setelah dibuat. Maka saat kita menulis ulang:

monthly_salary = 6_000_000
Enter fullscreen mode Exit fullscreen mode

Yang terjadi bukanlah mengganti isi variabel lama, melainkan membuat nilai baru dan mengikat ulang nama monthly_salary ke nilai tersebut. Proses ini disebut rebinding.

Dengan kata lain, rebinding berarti memperbarui hubungan antara sebuah nama dan nilai yang berbeda. Nilai sebelumnya tetap ada, tetapi tidak lagi terhubung ke nama tersebut.

Contoh:

iex> monthly_salary = 5_000_000   
5000000

iex> monthly_salary             
5000000

iex> monthly_salary = 5_123_000   
5123000

iex> monthly_salary             
5123000
Enter fullscreen mode Exit fullscreen mode

Penjelasan:

  • ❶ Nama monthly_salary pertama kali di-bind ke nilai 5_000_000.
  • ❷ Ketika diperiksa, monthly_salary menunjuk ke 5_000_000.
  • ❸ Nama yang sama di-rebind ke nilai baru 5_123_000.
  • ❹ Sekarang monthly_salary menunjuk ke nilai yang baru.

Nilai lama (5_000_000) tetap ada di memori untuk sementara, tetapi tidak lagi dirujuk oleh nama mana pun. Elixir akan mengelola dan membebaskan memori dari nilai yang tidak digunakan melalui mekanisme garbage collection. Kita tidak perlu menghapus nilai tersebut secara manual.

Manajemen Memori di Elixir

Elixir dilengkapi dengan garbage collector (GC), yaitu bagian dari runtime yang bertugas mengelola memori secara otomatis. Tugas utamanya adalah mendeteksi data yang sudah tidak lagi digunakan, lalu membebaskan memori yang ditempati data tersebut.

Sebagai contoh, perhatikan kasus rebinding berikut:

iex> monthly_salary = 5_000_000

iex>monthly_salary = 6_000_000
Enter fullscreen mode Exit fullscreen mode

Setelah baris kedua dijalankan, nama monthly_salary tidak lagi merujuk ke nilai 5_000_000, melainkan ke nilai baru 6_000_000. Karena tidak ada lagi nama lain yang menunjuk ke nilai 5_000_000, nilai tersebut dianggap tidak dibutuhkan. Garbage collector akan membebaskan memori yang sebelumnya digunakan oleh nilai itu.

Semua proses ini berjalan otomatis di balik layar. Kita tidak perlu mengatur alokasi atau dealokasi memori secara manual. Elixir akan mengurusnya untuk kita, sehingga kita bisa fokus sepenuhnya pada logika program.

Referensi

  • Saša Jurić. (2024). Elixir In Action (3rd ed.). Manning Publications.

Top comments (0)