Memakai Currying Pada Closure Di Groovy


Berdasarkan informasi dari Wikipedia, currying adalah sebuah teknik transformasi fungsi pada bidang matematika dan ilmu komputer yang diperkenalkan oleh Moses Schonfinkel dan dipopulerkan oleh Haskell Curry.   Closure pada Groovy mendukung currying, tapi sebenarnya apa itu currying?   Saya akan mengawali ilustrasi dengan sebuah pemanggilan closure biasa seperti berikut ini:

def query = { String namaModel, boolean barisTunggal, Map where ->
   println "Melakukan query untuk mencari $namaModel"
   where.each { k,v -> println "Dengan kondisi $k = $v" }
   if (barisTunggal) {
       "Data $namaModel"
   } else {
       ["Data $namaModel #1", "Data $namaModel #2"]
   }
}

//
// Output:
// Melakukan query untuk mencari mahasiswa
// Dengan kondisi nama = Jocki
// Dengan kondisi lulus = true
// Data mahasiswa
//
println query('mahasiswa', true, [nama: 'Jocki', lulus: true])

//
// Output:
// Melakukan query untuk mencari mahasiswa
// Dengan kondisi nama = Jocki
// [Data mahasiswa #1, Data mahasiswa #2]
//
println query('mahasiswa', false, [nama: 'Jocki'])

//
// Output:
// Melakukan query untuk mencari kelas
// Dengan kondisi kode = 1AC
// Data kelas
//
println query('kelas', true, [kode: '1AC'])

Pada kode program di atas, anggap saja closure query dipakai untuk membaca data dari database.   Ia membutuhkan argumen berupa sebuah namaModel yang mewakili nama tabel yang akan dibaca.   Ia juga memiliki argumen barisTunggal yang jika bernilai true akan selalu mengembalikan sebuah record; sebaliknya jika bernilai false, maka yang dikembalikan adalah sebuah List berisi satu atau lebih record.   Saya juga dapat menyertakan kondisi pencarian dalam bentuk sebuah Map.

Sekilas, pemanggilan closure query terlihat kompleks karena harus memberikan banyak parameter.   Oleh sebab itu, saya dapat menggunakan currying untuk me-‘reduksi‘ closure tersebut menjadi lebih terspesialisasi (dengan cara memastikan parameter tertentu selalu sama nilainya).   Sebagai contoh, saya dapat menghasilkan queryMahasiswa dan queryKelas yang khusus untuk mencari tabel-nya masing-masing, seperti pada kode program berikut ini:

def query = { String namaModel, boolean barisTunggal, Map where ->
   println "Melakukan query untuk mencari $namaModel"
   where.each { k,v -> println "Dengan kondisi $k = $v" }
   if (barisTunggal) {
       "Data $namaModel"
   } else {
       ["Data $namaModel #1", "Data $namaModel #2"]
   }
}

def queryMahasiswa = query.curry('mahasiswa')
println queryMahasiswa(true, [nama: 'Jocki', lulus: true])
println queryMahasiswa(false, [nama: 'Jocki'])

def queryKelas = query.curry('kelas')
println queryKelas(true, [kode: '1AC'])

Kode program di atas menghasilkan output yang sama seperti sebelumnya, tetapi kini terdapat queryMahasiswa dan queryKelas yang dihasilkan dari query, dimana parameter pertama-nya selalu di-isi dengan nilai yang telah ditentukan (yakni 'mahasiswa' dan 'kelas').   Ini disebut juga dengan partial function application.

Pada contoh berikut ini, saya kembali melakukan ‘spesialisasi’ lagi dimana terdapat closure yang hanya mengembalikan record tunggal dan juga terdapat closure yang mengembalikan lebih dari satu record:

def query = { String namaModel, boolean barisTunggal, Map where ->
   println "Melakukan query untuk mencari $namaModel"
   where.each { k,v -> println "Dengan kondisi $k = $v" }
   if (barisTunggal) {
       "Data $namaModel"
   } else {
       ["Data $namaModel #1", "Data $namaModel #2"]
   }
}

def cariSeluruhMahasiswa = query.curry('mahasiswa', false)
def cariMahasiswa = query.curry('mahasiswa', true)
def cariSeluruhKelas = query.curry('kelas', false)
def cariKelas = query.curry('kelas', true)

println cariMahasiswa([nama: 'Jocki', lulus: true])
println cariSeluruhMahasiswa([nama: 'Jocki'])
println cariKelas([kode: '1AC'])
Contoh Penggunaan Currying

Contoh Penggunaan Currying

Seluruh contoh program di atas mengembalikan hasil yang sama dan memiliki implementasi kode program yang satu (dimana isi closure query tidak berubah).   Walaupun demikian, versi terakhir di atas terlihat lebih mudah dimengerti dan lebih rapi karena argumen yang dilewatkan lebih sedikit.

Perihal Solid Snake
I'm nothing...

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: