This is a follow-up to my earlier question.
I came up with a bizarre object scheme from my reading of Let Over Lambda and can think of no advantages over protocols, but want to get opinions. I am just exploring the use of higher-order functions and encapsulation.
(defn new-person
"Construct a new Person object and return a Map of accessor methods."
[init-first-name init-last-name init-age]
(let [first-name (ref init-first-name)
last-name (ref init-last-name)
age (ref init-age)]
{:get-first-name #(@first-name)
:set-first-name #(dosync (ref-set first-name %1))
:get-last-name #(@last-name)
:set-last-name #(dosync (ref-set last-name %1))
:get-age #(@age)
:set-age #(dosync (ref-set age %1))}))
I can use the object like this:
(def fred (new-person "fred" "flintstone" 42))
and retrieve an accessor method this way:
(fred :get-age)
but I can't figure out how to call the accessor.
The object created is thread-safe since all mutation of "instance" variables occurs in the STM.
UPDATE: New and improved version:
(defn new-person
"Construct a new Person object and return a Map of accessor methods."
[init-first-name init-last-name init-age]
(let [first-name (ref init-first-name)
last-name (ref init-last-name)
age (ref init-age)]
{:first-name
(fn
([] @first-name)
([val] (dosync (ref-set first-name val))))
:last-name
(fn
([] @last-name)
([val] (dosync (ref-set last-name val))))
:age
(fn
([] @age)
([val] (dosync (ref-set age val))))}))