|
|
|
|
|
by harperlee
2007 days ago
|
|
Through an atom (https://clojuredocs.org/clojure.core/atom). The idea of accesing a closure that is mutable is as follows: (let [temp (atom 0)]
(defn getter [] @temp)
(defn setter [val] (reset! temp val)))
To implement an object, you would do something more like: (defn new-object [init-val]
(let [temp (atom init-val)]
{:getter (fn [] @temp)
:setter (fn [val] (reset! temp val))}))
(def obj (new-object 0))
((:setter obj) 12)
To define interfaces, you could check whether the map/object conforms to a spec, etc.But obviously all this is not very idiomatic; in clojure you would keep those functions first-class through defn instead of tying them to the object / map, and would pass state as an argument. Something like: (defn getter [obj] @obj)
(defn setter [obj val] (reset! obj val))
(def obj (atom 0)) ; This gives you the ability (and need)
; to explicitly track the list of
; existing objects in use lest they are garbage collected.
(setter obj 12)
If obj has structure (e.g. it is a map such as {:type :my.personal/type :val 12}) you can identify its type through the type keyval and can check conformance to a spec, etc.As it was said in the previous post, it's equivalent. It's a matter of how to organize code. |
|