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?
- OOP vs Functional: Dua Dunia Berbeda
- Konsep Inti Functional Programming
- Studi Kasus: Ubah Kode Imperatif ke Fungsional
- Functional Programming di Dunia Nyata
- Kesimpulan
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.
| Paradigma | Cara Mikir | Contoh 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:
| Aspek | OOP | Functional Programming |
|---|---|---|
| Unit utama | Objek (data + method) | Fungsi murni |
| State | Bisa berubah (mutable) via method | Tidak berubah (immutable) |
| Data & behavior | Digabung dalam class | Dipisah — fungsi bekerja pada data |
| Effect samping | Biasa terjadi | Dihindari sebisa mungkin |
| Loop | for, while | Recursion, map, filter, reduce |
| Contoh bahasa | Java, 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
| Domain | Contoh Penggunaan FP |
|---|---|
| Web frontend | React (komponen sebagai fungsi murni + immutability via useState) |
| Data processing | Apache Spark, Pandas (map/filter/reduce pattern) |
| Backend services | Elixir/Phoenix untuk high-concurrency, Scala/Akka untuk reactive systems |
| Financial systems | Haskell digunakan di Standard Chartered, Barclays — karena keandalan pure function |
| Machine Learning | JAX, PyTorch functional API — transformasi data tanpa mutasi |
| Distributed systems | Erlang/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
| Aspek | Intinya |
|---|---|
| Apa itu FP? | Paradigma yang fokus pada “apa yang dihasilkan” bukan “gimana caranya” |
| Pure function | Fungsi deterministik tanpa side effect — gampang dites dan di-debug |
| Immutability | Data tidak pernah diubah, selalu dibuat baru — aman untuk concurrent code |
| Higher-order function | Map, filter, reduce — tulis kode lebih ekspresif dengan lebih sedikit baris |
| Recursion | Gantinya 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.
Related Posts
- OOP (Object Oriented Programming) — Konsep, 4 Pilar, dan Contoh Lengkap — Paradigma OOP yang sering dibandingkan dengan FP, plus perbedaan pendekatan keduanya
- Fungsi dalam Programming — Blok Bangunan yang Bikin Kode Rapi — Fondasi fungsi sebelum masuk ke konsep functional programming
- Algoritma dan Logika Dasar — Bekal Wajib Setiap Programmer — Logika dasar yang jadi fondasi semua paradigma programming