≡ Menu

Dive in Clojure: partial

Pertamanya agak bingung dengan fungsi partial ini, tapi setelah ketemu contoh praktikalnya jadi Ngeh kenapa fungsi partial ada.

Menurut clojuredocs:

Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args.

Fungsi partial digunakan ketika kita sudah tahu fungsi apa yang harus kita gunakan, tetapi argumennya belum siap.

Contohnya:

(def hundred-times (partial * 100))
 
(hundred-times 4 5 6)
;;=> 12000
 
;; masih bisa dengan defn
 
(defn hundred-times2
  [x & others]
  (apply * 100 x others))
 
(hundred-times2 4 5 6)
;;=> 12000

Contoh di atas menunjukan bahwa tanpa partial-pun masih bisa. Artinya partial hanya sekedar altenatif defn.

Special Case partial

Thanks to SICP, karena problem SICP saya ngeh ternyata partial bisa menjadi spesial, bukan sekedar alternatif defn saja.

Kita ambil contoh fungsi yang menerima dua argumen atau lebih seperti conj. conj adalah fungsi yang digunakan untuk menambahkan emelen pada list.

(conj [1 2 3] 4 5 6 7)
 
;;=> [1 2 3 4 5 6 7]

Sekarang bagaimana jika [1 2 3] sudah diketahui, tetapi elemen yang ditambahkan belum siap?

((partial conj [1 2 3]) 4 5 6 7)
 
;;=> [1 2 3 4 5 6 7]

Ingat bahwa partial adalah fungsi yang mengemlabilak fungsi.

Contoh lainnya, cek apakah suatu karakter, karakter vokal atau bukan?

Okay, saya tahu bisa dengan if-condition, cond, dsb. Tetapi itu sangat tidak elegan. partial menunjukan bagaimana membuat fungsi cek vokal bisa lebih elegan.

(def vokal? #(some (partial = %) "aiueo"))
 
(vokal? \a)
;;=> true
 
(vokal? \e)
;;=> true
 
(vokal? \z)
;;=> nil

Tanpa fungsi partial, jika kita keukeuh masih ingin menggunakan fungsi some, fungsi ini akan seperi:

(def vokal? #(some (fn [x] (= x %)) "aiueo"))
 
(vokal? \a)
;;=> true
 
(vokal? \e)
;;=> true
 
(vokal? \z)
;;=> nil

Jelas kan? dengan partial kita bisa membuat fungsi lambda jadi lebih elegan.

(def vokal? #(some (partial = %) "aiueo"))
;; vs
(def vokal? #(some (fn [x] (= x %)) "aiueo"))

Karena hash-lambda tidak boleh double, alternatifnya dengan fn. Tetapi jika ingin lebih elegan, dengan partial.

{ 1 comment… add one }

Leave a Comment