Function di Kotlin adalah first-class citizen — dapat disimpan ke variabel, diteruskan sebagai argumen, dan dikembalikan dari function lain. Function yang menerima function sebagai parameter atau mengembalikan function disebut higher-order function. Pola ini memungkinkan kita menulis ulang logika umum seperti transformasi, filter, dan komposisi tanpa duplikasi. Pada chapter ini kita akan membongkar tiga pola higher-order function yang paling sering dipakai.

Menerima Function sebagai Parameter #

Higher-order function paling dasar menerima function sebagai parameter. Pemanggil memberikan function (bisa berupa lambda, function reference, atau anonymous function), dan function induk memanggilnya di dalam body.

kotlin
fun apply(f: (Int) -> Int, x: Int): Int = f(x)

fun buatPenambah(n: Int): (Int) -> Int {
    return { x -> x + n }
}

fun prosesDaftar(data: List<Int>, transformasi: (Int) -> Int): List<Int> {
    val hasil = mutableListOf<Int>()
    for (n in data) hasil.add(transformasi(n))
    return hasil
}

fun main() {
    val kuadrat: (Int) -> Int = { x -> x * x }
    println("apply(kuadrat, 6) = ${apply(kuadrat, 6)}")

    val tambahLima = buatPenambah(5)
    println("tambahLima(10) = ${tambahLima(10)}")

    val data = listOf(1, 2, 3, 4, 5)
    val dikuadrat = prosesDaftar(data, kuadrat)
    println("Dikuadrat: $dikuadrat")

    val ditambah = prosesDaftar(data, tambahLima)
    println("Ditambah lima: $ditambah")
}

Output yang Dihasilkan:

text
apply(kuadrat, 6) = 36
tambahLima(10) = 15
Dikuadrat: [1, 4, 9, 16, 25]
Ditambah lima: [6, 7, 8, 9, 10]

Mari kita bedah baris per baris:

  1. fun apply(f: (Int) -> Int, x: Int): Int = f(x): function apply menerima parameter f bertipe function (Int) -> Int. Di dalam body, f dipanggil dengan x. Parameter function ditulis dengan tanda panah -> antara tipe argumen dan tipe kembalian.
  2. fun buatPenambah(n: Int): (Int) -> Int: function yang mengembalikan function. Tipe kembalian adalah (Int) -> Int — sebuah function yang menerima Int dan mengembalikan Int.
  3. val tambahLima = buatPenambah(5): pemanggilan buatPenambah(5) mengembalikan lambda { x -> x + 5 } yang disimpan ke variabel tambahLima.
  4. prosesDaftar(data, kuadrat): function reference kuadrat diteruskan sebagai argumen. prosesDaftar memanggil transformasi(n) untuk setiap elemen data.

Mengembalikan Function #

Function yang mengembalikan function memungkinkan kita membuat function factory — function yang menghasilkan function khusus sesuai parameter. Lambda yang dikembalikan menutup variabel dari function induk (closure).

kotlin Contoh: function factory dengan closure
fun buatPengali(faktor: Int): (Int) -> Int {
    return { x -> x * faktor }
}

fun main() {
    val kaliDua = buatPengali(2)
    val kaliSepuluh = buatPengali(10)
    println(kaliDua(5))      // 10
    println(kaliSepuluh(5))  // 50
}

buatPengali(2) mengembalikan lambda yang selalu mengalikan input dengan 2. Variabel faktor dari function induk ditangkap oleh lambda — bahkan setelah buatPengali selesai dieksekusi, lambda tetap dapat mengakses nilai faktor.

Pola Umum: Map, Filter, Fold #

Standard library Kotlin menyediakan banyak higher-order function siap pakai untuk koleksi. Tiga yang paling sering dipakai adalah map, filter, dan fold. Memahami pola ini membantu kita menulis ulang versi kustom bila kebutuhan berbeda.

kotlin Contoh: pola map dan filter
fun main() {
    val data = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

    val dikuadrat = data.map { it * it }
    val genap = data.filter { it % 2 == 0 }
    val total = data.fold(0) { acc, n -> acc + n }

    println("Dikuadrat: $dikuadrat")
    println("Genap: $genap")
    println("Total: $total")
}

Lambda it adalah nama default parameter tunggal — kita akan membahasnya tuntas pada section Lambdas dan Functional Programming. Pemakaian it membuat pemanggilan ringkas untuk transformasi sederhana.

Manfaat Higher-Order Function #

Higher-order function memberi tiga manfaat utama:

  • Reuse: logika traversal atau transformasi ditulis sekali, dipakai banyak tempat dengan function berbeda
  • Komposisi: function dapat dirangkai menjadi pipeline (data.map { ... }.filter { ... }.fold { ... })
  • Abstraksi: detail cara iterasi disembunyikan, pemanggil fokus pada apa yang dilakukan ke setiap elemen

Referensi Lanjutan #

Ringkasan #

Higher-order function menerima atau mengembalikan function sebagai nilai. Pola ini memungkinkan kita menulis ulang logika traversal dan transformasi tanpa duplikasi. Lambda yang dikembalikan dapat menutup variabel dari function induk (closure). Pada chapter Function Types berikutnya, kita akan membedah secara rinci cara menuliskan tipe function sebagai (Int) -> Int atau dengan receiver type Int.(Int) -> Int.