Functional Programming — Paradigma Deklaratif yang Bikin Kode Lebih Prediktibel

📋 Daftar Isi

Functional Programming — Paradigma Deklaratif yang Bikin Kode Lebih Prediktibel

“Kalau OOP itu kayak pabrik dengan berbagai departemen yang saling kirim memo, Functional Programming itu kayak dapur dengan resep-resep murni — setiap resep ngubah bahan jadi masakan tanpa mengubah dapurnya sendiri. Hasilnya? Setiap kali kamu masak dengan resep yang sama, rasanya persis sama.”

Daftar Isi


Apa Itu Functional Programming?

Functional Programming (FP) adalah paradigma pemrograman yang memperlakukan komputasi sebagai evaluasi fungsi matematika — dan menghindari perubahan state serta data yang bisa berubah (mutable).

Bunyi ribet? Sederhananya begini:

Dalam FP, kamu jelasin apa yang mau dihasilkan, bukan gimana cara ngasilinya.

Ini kebalikan dari cara kita biasanya nulis kode (paradigma imperatif) di mana kita kasih instruksi step-by-step ke komputer.

Contoh paling gampang: kopi.

ParadigmaCara MikirContoh Analogi
Imperatif”Nyalain kompor → taruh panci → masak air → masukin kopi → aduk → tuang ke gelas”Kamu ngasih resep step-by-step
Fungsional”Kopi adalah hasil dari menuangkan air panas ke bubuk kopi yang sudah disaring”Kamu ngasih definisi dari hasil akhirnya

Dalam FP, kamu bikin fungsi-fungsi kecil yang masing-masing melakukan satu hal, lalu menggabungkannya kayak Lego.


OOP vs Functional: Dua Dunia Berbeda

Setelah kita bahas OOP (Object Oriented Programming) di artikel sebelumnya, sekarang saatnya kita lihat perbandingannya dengan FP:

AspekOOPFunctional Programming
Unit utamaObjek (data + method)Fungsi murni
StateBisa berubah (mutable) via methodTidak berubah (immutable)
Data & behaviorDigabung dalam classDipisah — fungsi bekerja pada data
Effect sampingBiasa terjadiDihindari sebisa mungkin
Loopfor, whileRecursion, map, filter, reduce
Contoh bahasaJava, C++, Python, C#Haskell, Elixir, Clojure, Scala, F#

Yang menarik: banyak bahasa modern sekarang hybrid — JavaScript, Python, Kotlin, dan Swift bisa pake kedua paradigma. Bahkan Java sejak versi 8 mulai nambahin fitur functional kayak lambda dan stream API.


Konsep Inti Functional Programming

1. Pure Function

Pure function adalah fungsi yang:

  • Deterministik: Input yang sama → output yang sama selalu
  • Tanpa side effect: Tidak mengubah variabel di luar, tidak nge-print ke console, tidak nulis file, tidak nge-hit API
# ❌ BUKAN pure function — hasilnya tergantung variabel global
diskon = 0.1
def hitung_harga(harga):
    return harga * (1 - diskon)

# ✅ Pure function — semua dependensi lewat parameter
def hitung_harga_pure(harga, diskon):
    return harga * (1 - diskon)

Kenapa pure function penting?

  • Gampang dites — tinggal kasih input, cek output
  • Gampang di-debug — nggak ada “side effect misterius”
  • Bisa di-cache (memoization) — karena hasilnya deterministik

2. Immutability

Immutability berarti data tidak bisa diubah setelah dibuat. Kalau mau “ubah”, kamu bikin data baru.

// ❌ Mutasi langsung — ini mengubah array asli
const angka = [1, 2, 3];
angka.push(4);  // array asli berubah!

// ✅ Immutable — bikin array baru
const angka2 = [1, 2, 3];
const angkaBaru = [...angka2, 4];  // array asli tetap utuh

Keuntungan immutability:

  • Nggak ada bug “siapa yang ngubah data saya?” — data asli dijamin aman
  • Thread-safe — cocok buat concurrent programming
  • Time-travel debugging — karena data lama nggak hilang, kamu bisa “mundur” ke state sebelumnya

3. Higher-Order Function

Higher-order function adalah fungsi yang:

  • Menerima fungsi lain sebagai argumen, atau
  • Mengembalikan fungsi lain sebagai hasil

Ini adalah senjata utama FP. Contoh paling terkenal: map, filter, reduce.

data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Imperatif (gimana caranya)
hasil = []
for angka in data:
    if angka % 2 == 0:
        hasil.append(angka ** 2)

# Fungsional (apa yang dihasilkan) — pake higher-order function
hasil = list(map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, data)))
#                                       ^ filter adalah higher-order function
#                    ^ map juga higher-order function

# Atau pake list comprehension — lebih Pythonic
hasil = [x ** 2 for x in data if x % 2 == 0]

Di JavaScript, map, filter, dan reduce sudah jadi daily driver:

const users = [
  { name: 'Budi', age: 25, active: true },
  { name: 'Siti', age: 17, active: true },
  { name: 'Agus', age: 30, active: false },
];

// Ambil nama user aktif yang sudah dewasa, diurutkan
users
  .filter(u => u.active && u.age >= 18)   // filter
  .map(u => u.name)                        // transform
  .sort();                                 // urutkan
// Hasil: ['Agus', 'Budi']

4. Recursion

Di FP, recursion (fungsi yang memanggil dirinya sendiri) menggantikan loop. Kenapa? Karena loop biasanya melibatkan perubahan counter variable (mutasi), dan FP menghindari mutasi.

-- Haskell: contoh recursion untuk faktorial
faktorial :: Int -> Int
faktorial 0 = 1           -- base case
faktorial n = n * faktorial (n - 1)  -- recursive case
// JavaScript: recursion untuk menghitung total array
function total(arr) {
  if (arr.length === 0) return 0;          // base case
  return arr[0] + total(arr.slice(1));     // recursive case
}

total([1, 2, 3, 4, 5]); // 15

Tapi hati-hati: Recursion bisa bikin stack overflow kalau terlalu dalam. Bahasa functional murni kayak Haskell punya tail call optimization (TCO) yang mencegah ini. Di JavaScript dan Python, recursion yang terlalu dalam tetap bisa overflow.

5. First-Class Function

Di FP, fungsi adalah warga kelas satu (first-class citizen) — artinya fungsi bisa:

  • Disimpan dalam variabel
  • Dijadikan argumen fungsi lain
  • Dikembalikan dari fungsi
  • Disimpan dalam array atau object
// Fungsi sebagai nilai
const greet = (nama) => `Halo, ${nama}!`;

// Fungsi sebagai argumen
function withLogging(fn) {
  return function(...args) {
    console.log(`Memanggil fungsi dengan args: ${args}`);
    return fn(...args);
  };
}

const greetWithLog = withLogging(greet);
greetWithLog('Budi'); // Console: Memanggil fungsi dengan args: Budi
                      // Return: "Halo, Budi!"

Ini memungkinkan pola function composition — menggabungkan fungsi kecil jadi pipeline besar:

const toUpper = (s) => s.toUpperCase();
const exclaim = (s) => `${s}!`;
const repeat = (s) => `${s} ${s}`;

const compose = (...fns) => (x) => fns.reduceRight((acc, fn) => fn(acc), x);

const shout = compose(repeat, exclaim, toUpper);
shout('halo'); // "HALO! HALO!"

Studi Kasus: Ubah Kode Imperatif ke Fungsional

Bayangin kita punya data penjualan dan mau: hitung total penjualan produk yang harganya di atas 50rb dan sudah dibayar.

// ===== IMPERATIF (gimana caranya) =====
const transaksi = [
  { produk: 'Mouse', harga: 75000, dibayar: true },
  { produk: 'Keyboard', harga: 150000, dibayar: true },
  { produk: 'USB Cable', harga: 25000, dibayar: true },
  { produk: 'Monitor', harga: 2000000, dibayar: false },
  { produk: 'Mouse Pad', harga: 45000, dibayar: true },
];

let total = 0;
for (let i = 0; i < transaksi.length; i++) {
  if (transaksi[i].harga > 50000 && transaksi[i].dibayar) {
    total += transaksi[i].harga;
  }
}
// total = 225000 (Mouse + Keyboard)

// ===== FUNGSIONAL (apa yang dihasilkan) =====
const totalFP = transaksi
  .filter(t => t.harga > 50000 && t.dibayar)   // filter dulu
  .map(t => t.harga)                              // ambil harganya
  .reduce((acc, harga) => acc + harga, 0);        // jumlahkan
// totalFP = 225000

Versi fungsional lebih deklaratif — kamu baca kodenya kayak cerita: “ambil transaksi, filter yang harga > 50rb dan dibayar, ambil harganya, jumlahkan.”


Functional Programming di Dunia Nyata

DomainContoh Penggunaan FP
Web frontendReact (komponen sebagai fungsi murni + immutability via useState)
Data processingApache Spark, Pandas (map/filter/reduce pattern)
Backend servicesElixir/Phoenix untuk high-concurrency, Scala/Akka untuk reactive systems
Financial systemsHaskell digunakan di Standard Chartered, Barclays — karena keandalan pure function
Machine LearningJAX, PyTorch functional API — transformasi data tanpa mutasi
Distributed systemsErlang/Elixir untuk fault-tolerant systems (WhatsApp, Discord)

Fun fact: WhatsApp cuma punya ~50 engineer pas diakuisisi Facebook $19 miliar — karena pakai Erlang (bahasa functional) yang luar biasa stabil untuk concurrent messaging.


Kesimpulan

AspekIntinya
Apa itu FP?Paradigma yang fokus pada “apa yang dihasilkan” bukan “gimana caranya”
Pure functionFungsi deterministik tanpa side effect — gampang dites dan di-debug
ImmutabilityData tidak pernah diubah, selalu dibuat baru — aman untuk concurrent code
Higher-order functionMap, filter, reduce — tulis kode lebih ekspresif dengan lebih sedikit baris
RecursionGantinya loop, pakai fungsi yang panggil diri sendiri
Kapan pakai?Data processing, concurrent systems, frontend modern, dan sistem yang butuh keandalan tinggi

Functional Programming bukan cuma teori akademik — React, Redux, Spark, dan banyak tool modern mengadopsi prinsip-prinsip FP. Bahkan kalau bahasa utama kamu Java atau Python, ngerti FP bakal bikin kode kamu lebih rapi, mudah dites, dan lebih sedikit bug.

Mulai pelan-pelan: coba pake map ganti for loop, hindari mutasi array, dan bikin fungsi-fungsi kecil yang pure. Nggak perlu langsung jadi master Haskell — yang penting mulainya dulu.

💬 Komentar