-
Notifications
You must be signed in to change notification settings - Fork 5
ObjectAccessorMethods
Luo Tian edited this page Sep 24, 2018
·
6 revisions
As fun-map can wrap functions inside, like this:
(defn numbers-obj
[numbers]
(fun-map
{:numbers numbers
:cnt (fnk [numbers] (count numbers))
:sum (fnk [numbers] (reduce + 0 numbers))
:average (fnk [cnt sum] (float (/ sum cnt)))}))Does it look like a constructor for a class numbers, which has property accessor like :cnt, :sum, :average? Indeed, you can access these properties as if they are stored inside.
(:average (numbers-obj [3 5 6 9])) ;=> 5.75What if instead of functions returning plain value, we return a function?
(defn numbers-with-methods
[numbers-obj]
(assoc numbers-obj
:average> (fnk [average]
(fn [another-numbers]
(> average (:average another-numbers))))))
(def numbers-1 (numbers-with-methods (numbers-obj [3 5 6 8 12])))
(def numbers-2 (numbers-obj [8 1 -3 18]))
((:average> numbers-1) numbers-2) ;=> trueThis :average> looks just like a method of numbers-with-methods object from the perspective of OO. Of course, it is cumbersome to call a method like this. We can introduce some syntax here.
(defmacro +>
[obj method-name & args]
`(('~method-name ~obj) ~@args))
(+> numbers-1 :average> numbers-2) ;=> trueThese numbers-obj objects are immutable data, but if we like mutable data structure like in another OO, nothing stops we do so:
(def a-numbers (atom [3 5 6 8]))
(def mutable-numbers (numbers-obj a-numbers))
(:average mutable-numbers) ;=> 5.5
(reset! a-numbers [8 15 7 22 -6])
(:average mutable-numbers) ;=> 9.2We made no changes to the code, created a mutable numbers-obj!