Fork me on GitHub

Sorry but after all the discussion about encapsulation, I still find that hiding (encapsulating) internal implementation of "complex" mechanisms (not silly field values like in Java) is a reasonable thing for helping others/self use of components without shooting one's own foot or scanning dozens of fns to figure what is meant to be used from the outside

Alex Miller (Clojure team)14:06:15

matan: well, you’re arguing against something I didn’t say. I didn’t say that all encapsulation was bad, I said needless encapsulation of data is bad and OO as typically practiced encapsulates all data.


When I have a complex side-effecting machine with a simple use interface, I reach for a protocol. You can also convey intentions about var usage with namespace design.


@U04V4HWQ4 what’s an example of using namespace design? I might be overthinking the meaning, but I haven’t heard that term before.


Maybe better examples but one that jumps to mind is core.async, where there is a public api (clojure.core.async) and a bunch of impl namespaces (e.g. clojure.core.async.impl.buffers)


(and that's why we have namespace private declarations I think)

Alex Miller (Clojure team)14:06:52

matan: note that even private vars are still accessible - anyone can obtain and use them still. The private meta is really more documentation than encapsulation.


that’s a good insight; i think the clojure difference is probably avoiding 1. colocating state with logic in memory 2. requiring encapsulated fn A to bring B, C, D, E, F and all their dependencies with it


@matan this belongs in #off-topic since this is not about clojure.spec (or even clojure itself) FYI


How would I rewrite this to avoid duplication? (s/def ::PrimaryContact (s/keys :req-un [::FirstName ::LastName ::Email] :opt-un [::Title ::Company ::Type ::Phone ::Fax])) (s/def ::SecondaryContact (s/keys :req-un [::FirstName ::LastName ::Email] :opt-un [::Title ::Company ::Type ::Phone ::Fax]))

Alex Miller (Clojure team)19:06:50

(s/def ::Contact (s/keys :req-un [::FirstName ::LastName ::Email]
                                :opt-un [::Title ::Company ::Type ::Phone ::Fax])
(s/def ::PrimaryContact ::Contact)
(s/def ::SecondaryContact ::Contact)


ah, well that's easy... thanks!