Kotlin: Mengenal Anonymous Function dan Lambda

Kotlin merupakan bahasa pemrograman fungsional sehingga Kotlin mempunyai Anonymous Function dan Lambda. Kedua-duanya banyak digunakan pada aplikasi nyata, terutama Lambda. Lambda dan Anonymous Function ini merupakan bentuk lain dari Fungsi

Anonymous Function dan Lambda erat kaitannya dengan menyimpan sebuah fungsi ke dalam variabel. Karena kita menyimpan fungsi ke dalam variabel, maka kita harus mengetahui tipe data dari sebuah fungsi.

Tipe Data Fungsi

Fungsi ternyata mempunyai tipe data.

Contohnya seperti ini: (String) -> Unit yang artinya adalah fungsi mempunyai 1 parameter bertipe data String dan menghasilkan nilai bertipe data Unit (tidak menghasilkan nilai apa pun). Saat mendeklarasikan tipe data untuk fungsi, maka tipe data kembalian harus dituliskan.

Contoh lainya adalah (Int, Int) -> Int yang artinya adalah fungsi mempunyai 2 parameter yang keduanya bertipe data Int dan menghasilkan nilai bertipe data Int.

Menyimpan Fungsi di Dalam Variabel

Fungsi dapat dimasukkan ke dalam sebuah variabel.

fun sayName(name: String) {
    if (name == "")
        return

    println("My name is $name")
}

val say: (String) -> Unit = ::sayName

:: digunakan untuk mereferensikan fungsi global.

Contoh yang lebih kompleks:

fun add(left: Int, right: Int) = left + right

val tambah: (Int, Int) -> Int = ::add

Fungsi yang disimpan di variabel bisa dipanggil dengan dua cara, yaitu: memanggilnya dengan operator invoke dan memanggilnya seperti fungsi biasa.

say.invoke("Jikri") // My name is Jikri
say("Lipi") // My name is Lipi

println(tambah.invoke(5 + 9)) // 14
println(tambah(10 + 12)) // 22

Anonymous Function

Kotlin mempunyai anonymous function. Anonymous function merupakan fungsi yang dideklarasikan sebagai ekspresi sehingga bisa langsung dimasukkan ke variabel. Anonymous function dibuat seperti fungsi biasa, namun bedanya nama fungsi dihilangkan.

val kurangi = fun (left: Int, right: Int): Int {
    return left - right
}

println(kurangi(10, 5)) // 5

Anonymous function juga bisa dibuat dengan Single-expression function. Fungsi di atas dapat ditulis juga sebagai:

val kurangi = fun (left: Int, right: Int) = left - right

Lambda

Lambda merupakan alternatif dari Anonymous function. Sintak lambda lebih ringkas daripada Anonymous function. Fungsi di atas dapat kita tulis sebagai lambda.

val kurangi = { left: Int, right: Int ->
    left - right
}

left dan right adalah nama parameter dan Int adalah tipe datanya. Kode setelah tanda -> adalah kode yang dijalankan.

Pada lambda, return tidak perlu digunakan untuk mengembalikan nilai, kembalian kode yang terakhir dijalankan digunakan sebagai kembalian. Tipe data yang dihasilkan lambda akan otomatis ditentukan berdasarkan nilai yang dihasilkan.

Contoh yang lebih kompleks:

val maksimum = { left: Int, right: Int ->
    println("Menentukan nilai maksimum dari $left dan $right")
    if (left > right) {
        println("$left > $right")
        left // mengembalikan nilai
    } else if (left < right) {
        println("$left < $right")
        right // mengembalikan nilai
    } else {
        println("$left = $right")
        right // mengembalikan nilai
    }
}

println(maksimum(10, 20))
// Menentukan nilai maksimum dari 10 dan 20
// 10 < 20
// 20
println(maksimum(50, 5))
// Menentukan nilai maksimum dari 50 dan 5
// 50 > 5
// 50
println(maksimum(25, 25))
// Menentukan nilai maksimum dari 25 dan 25
// 25 = 25
// 25

Kode yang ditandai dengan mengembalikan nilai akan mengembalikan nilai, karena kode tersebut merupakan kode yang terakhir dijalankan, sehingga kembalian kode tersebut dijadikan sebagai kembalian dari lambda.

Type Inference pada Parameter Lambda

Tipe data parameter pada lambda harus ditentukan. Tipe data parameter bisa ditentukan berdasarkan tipe data variabel yang akan menampung lambda.

val kurangi: (Int, Int) -> Int = {left, right -> left - right}

Tipe data parameter left dan right secara otomatis menjadi Int, karena berdasarkan tipe data (Int, Int) -> Int parameter ke 1 dan 2 bertipe data Int dan tipe data hasil lambda harus berupa Int.

Lambda Berparameter Tunggal

Dalam Kotlin kita akan sering menemui lambda yang hanya memiliki 1 parameter. Contohnya seperti berikut:

val kuadrat: (Int) -> Int = { angka -> angka * angka}
println(kuadrat(4)) // 16

Kode di atas masih bisa diringkas. Pada lambda berparameter tunggal, nama parameter dan -> bisa dihilangkan dan parameter dari lambda tersebut akan secara otomatis diberi nama it.

val kuadrat: (Int) -> Int = { it * it }
println(kuadrat(4)) // 16

Penyederhanaan ini hanya bisa dilakukan jika tipe data variabel yang akan menampung lambda ditentukan. Jadi (Int) -> Int tidak boleh dihilangkan.