DEV Community

loading...
Cover image for Jalan menuju pemahaman yang lebih baik melalui Elixir - Pemrograman Fungsional

Jalan menuju pemahaman yang lebih baik melalui Elixir - Pemrograman Fungsional

Iskandar Rizki
Full stack engineer
Updated on ・5 min read

Dalam mempelajari sebuah bahasa pemrograman, salah satu hal yang penting sebagai modal untuk sukses adalah memiliki motivasi dan alasan mempelajari-nya. Pada suatu proses interview saya pernah ditanya "bagaimana cara meyakinkan seorang programmer untuk mempelajari pemrograman fungsional ?". Terus terang agak kewalahan juga menjawabnya. Karena tidak ada alasan pragmatis untuk meyakinkan seorang programmer untuk mempelajari pemrograman fungsional.

Diantara alasan pragmatis seorang programmer mempelajari bahasa pemrograman yaitu banyak lapangan pekerjaan yang membutuhkan bahasa X, kemudian gaji programmer bahasa X paling tinggi. Dan alasan-alasan pragmatis tadi sepanjang sepengetahuan saya bekerja di Indonesia tidak banyak berlaku bagi seorang programmer fungsional, beberapa yang bekerja sebagai programmer ReactJS mungkin sebagai pengecualian. Sedangkan satu-satunya alasan yang terlintas dalam pikiran saya untuk mempelajari pemrograman fungsional adalah untuk menjadi programmer yang lebih baik.

Alasan untuk menjadi programmer yang lebih baik akan efektif jika seorang programmer telah memiliki pengalaman kurang beruntung dengan konsep OOP (Object Oriented Programming), atau tidak merasa puas dengan konsep OOP. Bukannya konsep OOP tidak bagus, tapi ada sesuatu yang kurang dengan OOP, walaupun konsep design pattern menyempurnakannya, banyak yang mungkin tidak mengadopsinya dan tidak menjadikan design pattern itu wajib diterapkan, dan mungkin ada yang merasa design pattern adalah sesuatu yang over engineered bagi konsep OOP. Jika ada yang merasakan hal yang sama, maka sudah waktunya untuk mencoba paradigma pemrograman lain yaitu pemrograman fungsional.

Pengalaman mencoba beberapa bahasa fungsional seperti Scala, Clojure dan kemudian Elixir, membuat saya merasakan Elixir adalah sebuah bahasa fungsional yang sangat "Down to Earth". Mungkin karena pencipta bahasa Elixir, yaitu Jose Valim memiliki latar belakang dari komunitas Ruby, dimana Ruby selalu mengedepankan "Developer Happiness", sehingga banyak konsep dari Ruby diadopsi ke dalam Elixir. Elixir sendiri adalah bahasa pemrograman yang berjalan diatas Erlang VM.

Kemudian pekan lalu teman dengan latar belakang bahasa Java yang menyatakan, "diantara Python, Golang dan Elixir, Elixir memiliki kurva pembelajaran (learning curve) yang paling tinggi". Hal tersebut sangat wajar sekali, karena diantara ketiga bahasa pemrograman tersebut memiliki paradigma yang berbeda. Python dengan konsep pragmatic OOP dan sedikit konsep fungsionalnya, Golang dengan konsep imperativenya, dipengaruhi dari bahasa C, kedua bahasa ini secara konsep sudah sangat familiar oleh sebagian besar programmer, dan yang berbeda adalah Elixir dengan konsep murni fungsional. Dan yang perlu diingat adalah, ketika melakukan programming dalam Elixir, konsep-konsep bahasa imperative dan OOP, seperti mutable object, konsep class dengan member, inheritance dan lain sebagainya harus juga dilupakan, dan setiap sifat (behaviour) dari bahasa imperative dan OOP tadi pasti ada penggantinya di Elixir. Dan saya akui bahwa dari pernyataan teman inilah yang membuat saya ingin mencoba menceritakan pengalaman dalam mempelajari Elixir.

Dari pengalaman mempelajari Elixir, saya melihat paling tidak ada dua konsep besar yang berperan dalam Elixir, dan bila kedua konsep ini dikuasai, maka saya yakin akan lancar dalam penggunaan bahasa ini. Kedua konsep tadi adalah konsep bahasa fungsional dari Elixir dan konsep Actor dari Erlang VM. Kedua konsep ini saling berperan dalam menciptakan sebuah sistem dengan kehandalan (reliability) yang sangat tinggi. Hal yang mencakup dalam konsep bahasa fungsional ada paling tidak tiga hal yang penting yaitu

  • immutable objects
  • declarative programming
  • higher order function

Pemrograman Fungsional di Elixir

  • mungkin sudah banyak yang mengenal tentang immutable objects, definisi bebasnya adalah memberlakukan seluruh nilai yang digunakan dalam proses pemrograman sebagai nilai yang tidak dapat diubah dari saat nilai tersebut dibentuk atau dideklarasikan sampai akhir masa berlakunya nilai tersebut.
    Untuk mempermudah pemahaman tentang immutable objects ini saya coba analogikan semua nilai immutable adalah data. Seperti kita tahu, data bersifat konstan dan merupakan fakta yang tidak berubah. Contoh data adalah "curah hujan di tanggal 5 September 2020", merupakan sebuah data yang nilainya tetap dan merupakan sebuah fakta.
    Programmer tidak bisa mengubah fakta tentang "curah hujan" di tanggal tersebut, tetapi yang bisa dilakukan adalah membuat data baru dari fakta tersebut. Dari banyak data di tanggal-tanggal bulan September, programmer dapat membuat data baru misalnya "rata-rata curah hujan di bulan September".
    Jadi demikian dianalogikan, bahwa jika seorang programmer menginginkan sebuah nilai yang dibutuhkan, programmer dapat membangun nilai baru tersebut dari kumpulan data-data atau nilai-nilai lain yang telah tersedia.
    Apa keuntungan menggunakan immutable objects ini ? Dalam concurrency programming seperti multi-threading atau multi-processing, seorang programmer tidak membutuhkan mutex atau mekanisme resource locking, karena semua nilai yang digunakan adalah read only, tiap thread bebas melakukan pembacaan pada nilai tersebut. Sehingga dengan immutability memastikan kondisi thread-safe dan memory-safe pada program.

  • seperti namanya declarative programming adalah kebalikan dari imperative programming. Dimana dalam imperative programming, seorang programmer secara eksplisit menuliskan semua perintah kepada program untuk menjalankan langkah-langkah yang harus dilakukan, pada declarative programming, tidak semua langkah-langkah harus diberikan secara eksplisit dari programmer pada program, hanya bagian yang penting saja perlu dituliskan pada program, hal yang bukan bagian penting telah didelegasikan kepada fungsi lain. Untuk lebih jelasnya berikut adalah contoh dari imperative programming,

    Dari contoh imperative programming diatas jelas terlihat setiap langkah diberikan instruksi oleh programmer, mulai dari inisialisasi nilai total, sampai proses looping diberikan secara detil langkah pengerjaannya. Bandingkan dengan declarative programming,
    Terlihat dari contoh diatas proses looping telah didelegasikan kepada fungsi Enum.reduce, secara implementasi programmer tidak tahu apakah looping yang dilakukan dari index terkecil atau terbesar, semua terserah implementasi fungsi Enum.reduce. Yang programmer lakukan hanya menentukan nilai inisialisasi seperti apa yang diinginkan dan apa yang harus dilakukan untuk nilai tiap item member, dimana nilai tiap item member ditambahkan dengan nilai total item sebelumnya yang disimpan dalam accumulator (acc). Apa keuntungannya jika programmer mengadopsi declarative programming ini ? Tentu saja kode yang dihasilkan akan lebih jelas dan ringkas (clear and concise), karena sebagian besar kode yang digunakan adalah fungsi yang telah dipercayakan pasti berjalan dengan baik dan benar, yang berasal dari bahasa Elixir itu sendiri maupun ekosistemnya. Dan tentu saja dapat memperkecil kecenderungan terjadinya kesalahan (error prone) pada program.
  • higher order function adalah sebuah konsep dimana setiap input dan output pada sebuah proses bukan hanya nilai tapi dapat berupa fungsi. Hal ini yang menyebabkan fungsi adalah sebuah bagian yang terpenting dari bahasa pemrograman Elixir. Contoh input output dapat berupa fungsi adalah sebagai berikut,

    Dapat dilihat pada contoh diatas, reduce_func merupakan sebuah pointer menuju fungsi. Dimana pointer ini dapat diberlakukan sebagai input maupun output. Pada fungsi anonim anon2 terlihat bahwa pointer fungsi reduce_func adalah output dari fungsi anon2. Pada fungsi anon2 juga terlihat bahwa anon1 merupakan input dari reduce_func. Terlihat pada bahasa Elixir pointer menuju fungsi ini dapat diberlakukan sebagai input maupun output. Sedikit tambahan variasi penulisan pointer menuju fungsi, juga dapat berbentuk seperti dibawah,
    Diatas terlihat bahwa fungsi anonim anon1 dapat digantikan dengan sintaks &(&2+&1*&1), untuk meringkaskan penulisan kode, tapi sedikit mengorbankan clarity atau kejelasan dari kode. Dengan higher-order function ini keuntungannya adalah keseluruhan program yang dibangun dari banyak fungsi-fungsi yang lebih kecil dibawahnya, sehingga dengan konsep ini dapat dibangun sebuah sistem yang memenuhi prinsip composability.

Selain ketiga konsep diatas, masih ada fitur-fitur bahasa Elixir yang merupakan variasi-variasi dari pemrograman fungsional, diantaranya adalah pipe operator (|>), konsep matching operator (=) dan pattern matching, pin operator (^), protocols, railway oriented programming, dan masih banyak lainnya.

Jika dipelajari lebih lanjut, maka akan terlihat sebenarnya konsep pemrograman fungsional adalah sebuah konsep yang cukup familiar di antara programmer, tetapi hanya diperlukan pembiasaan dan menanamkan mindset dari konsep-konsep pemrograman fungsional diatas. Untuk konsep pemrograman fungsional mungkin sampai disini dulu, untuk artikel yang berikutnya akan dibahas tentang pemrograman aktor di Elixir. Terima kasih.

Discussion (1)

Collapse
epsi profile image
E.R. Nurwijayadi

Hebatbang.

Salute-lah.

Forem Open with the Forem app