Jalan menuju pemahaman yang lebih baik melalui Elixir - Pemrograman Fungsional
Tags: erlang, elixir, betterprogrammer
Published: 2020-09-06 15:34:16

---
title: Jalan menuju pemahaman yang lebih baik melalui Elixir - Pemrograman Fungsional
series: Jalan menuju pemahaman yang lebih baik melalui Elixir
---
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)](https://id.wikipedia.org/wiki/Pemrograman_berorientasi_objek), 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*](https://id.wikipedia.org/wiki/Elixir_(bahasa_pemrograman)), 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](https://translate.google.com/translate?u=https://en.wikipedia.org/wiki/Erlang_(programming_language)&hl=id&sl=en&tl=id&client=srp&prev=search).

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](https://id.wikipedia.org/wiki/Pemrograman_imperatif) 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,
{% gist https://gist.github.com/rizki96/45104fa152b179938b11fa07c0062314 file=imperative.js %}
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,
{% gist https://gist.github.com/rizki96/45104fa152b179938b11fa07c0062314 file=declarative.ex %}
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,
{% gist https://gist.github.com/rizki96/45104fa152b179938b11fa07c0062314 file=input_output_func.ex %}
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,
{% gist https://gist.github.com/rizki96/45104fa152b179938b11fa07c0062314 file=input_output_func.ex-2 %}
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*](https://en.wikipedia.org/wiki/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](https://medium.com/elixirlabs/railway-oriented-programming-in-elixir-with-pattern-matching-on-function-level-and-pipelining-e53972cede98), 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.