I have some clojure code that looks like this:
(defn rect [x y w h]
{:x x, :y y, :w w, :h h})
(def left :x)
(def top :y)
(def width :w)
(def height :h)
(defn right [r]
(+ (left r) (width r)))
(defn bottom [r]
(+ (top r) (height r)))
Now the following code seems a bit uncommon:
(def left :x)
However I don't know any other way to get encapsulation.
Suppose, I later want to represent my rect a different way. Then relying on (:x rect) is not a good idea, because :x only works on hashmap's and records, so then I would be leaking implementation details in the api, which at least in OO languages is considered bad practice.
Now, if I decide to implement my rect in java instead, it gets even worse, because then I would have to write wrappers like:
(defn left [rect] (.getLeft rect))
to make sure the interface doesn't change.
How does clojure get around this problem?