Thanks John. To be explicit - the add method shouldn't be private - it is the only way users should add to the queue. I think this is what you meant but you wrote "..and `add` and `clear` are your private fns..".
Again, this paradigm shift of 'trust your users' is unfortunately alien to me based on my experience with most of the Java devs I have come across :). I say that not be snarky, but to highlight how much it really does change things. The open-closed principle now becomes much simpler to realise for example. Thanks again. On 10 May 2013 12:44, John D. Hume <duelin.mark...@gmail.com> wrote: > I agree with the advice you've gotten, but since no one has mentioned it, > I wanted to point out that you can have encapsulation w/o protocols with > something like this. > > Assume a queue is your only state and `add` and `clear` are your private > fns that take a queue as first argument. > > (defn new-scheduler [] > (let [queue (...)] > {:add (partial add queue) > :clear (partial clear queue)})) > > There are several disadvantages to this, however. The biggest in my book > is that it achieves your goal, and you're limited in the same way your > users are. You can't add behavior to an already created scheduler (unless > it's built on adding and clearing). Furthermore, if you dynamically > recompile `add` or `clear`, it won't change the behavior of an already > created scheduler, since partial has the fns, not the symbols or vars that > point at them. (These same disadvantages apply to a reified protocol.) > > As others have recommended, just return a map. Keep in mind that the > documentation is just a `(doc new-scheduler)` away and that auto-completion > will tend to send people back into your ns's fns rather than into the > internals of a data structure. > On May 10, 2013 5:51 AM, "Colin Yates" <colin.ya...@gmail.com> wrote: > >> Thanks Korny. >> >> Ok, the over-ridding theme seems to be: expose state, even if it is >> dangerous, but expect consumers to 'do the right thing' and read the >> documentation. >> >> I can see that. I guess I have worked (and to be honest, been guilty >> myself) with too many people who don't read the documentation, use >> auto-complete to find something that looks like it might work and then move >> on to the next chunk of wiring things up in XML :). >> >> I think I also got hung up on the 'data as a contract'. The point here >> is that I am not returning data, rather I am defining a service. A subtle >> difference but an important one I think. >> >> Keep the comments coming! >> >> >> On 10 May 2013 11:37, Korny Sietsma <ko...@sietsma.com> wrote: >> >>> I would generally handle this sort of encapsulation at the namespace >>> level. >>> >>> Put (create-woobly) and (add-job) and all the other woobly-related >>> functions into a woobly namespace. Also add any functions that access info >>> from a woobly bag-o-state, or mutate a woobly to make a woobly-with-extras. >>> >>> Functions that might dangerously expose internals of a woobly can be >>> made private, or possibly you can just document them in a way to warn folks >>> away from "bad" behaviour. >>> >>> While external users of (woobly/create-woobly) can in theory dig into >>> the internals of the woobly "object", but it should be relatively obvious >>> that this isn't a good idea. >>> >>> I'd defer making protocols until you actually need polymorphism. >>> >>> - Korny >>> >>> >>> >>> On 10 May 2013 03:03, Colin Yates <colin.ya...@gmail.com> wrote: >>> >>>> Thanks for all the helpful responses. >>>> >>>> One reason I want to hide the internals is that I don't want people to >>>> add jobs directly to the queue. (add-job) will put a map containing the >>>> provided function onto the queue. Not really relevant, but this is so that >>>> I can track queue timings that I can later on use to determine how much >>>> capacity the system can handle. >>>> >>>> I am nervous as well about "expose internals but trust people to do the >>>> right thing" because in this case, if I was a consumer and saw that queue, >>>> particularly given the emphasis about data being the contract etc. then why >>>> would I think *not* to use it. >>>> >>>> I do appreciate the point about not needlessly obfuscating information >>>> - this is a slightly different case. >>>> >>>> Sounds like in this case, either reify is the way to go or maybe return >>>> a bad of data but have this stuff in an 'internal' map (i.e. {:internal >>>> {:queue...}}) >>>> >>>> Thanks a bunch - really helpful. >>>> >>>> >>>> On 9 May 2013 17:30, James Reeves <ja...@booleanknot.com> wrote: >>>> >>>>> On 9 May 2013 17:07, Colin Yates <colin.ya...@gmail.com> wrote: >>>>> >>>>>> The part I am struggling with is how to create a Woobly without >>>>>> exposing its internals. >>>>>> >>>>> >>>>> To what end? What's the benefit? >>>>> >>>>> If you take a look at some internal data structures Clojure uses, like >>>>> zippers or protocols, you'll notice that they're just maps. In general >>>>> there's no need to try and obfuscate data to stop people from diving into >>>>> the internals; just don't provide a public API for the internal parts and >>>>> people will get the hint. >>>>> >>>>> - James >>>>> >>>>> -- >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Clojure" group. >>>>> To post to this group, send email to clojure@googlegroups.com >>>>> Note that posts from new members are moderated - please be patient >>>>> with your first post. >>>>> To unsubscribe from this group, send email to >>>>> clojure+unsubscr...@googlegroups.com >>>>> For more options, visit this group at >>>>> http://groups.google.com/group/clojure?hl=en >>>>> --- >>>>> You received this message because you are subscribed to a topic in the >>>>> Google Groups "Clojure" group. >>>>> To unsubscribe from this topic, visit >>>>> https://groups.google.com/d/topic/clojure/D2OBBPTxGfY/unsubscribe?hl=en >>>>> . >>>>> To unsubscribe from this group and all its topics, send an email to >>>>> clojure+unsubscr...@googlegroups.com. >>>>> >>>>> For more options, visit https://groups.google.com/groups/opt_out. >>>>> >>>>> >>>>> >>>> >>>> -- >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To post to this group, send email to clojure@googlegroups.com >>>> Note that posts from new members are moderated - please be patient with >>>> your first post. >>>> To unsubscribe from this group, send email to >>>> clojure+unsubscr...@googlegroups.com >>>> For more options, visit this group at >>>> http://groups.google.com/group/clojure?hl=en >>>> --- >>>> You received this message because you are subscribed to the Google >>>> Groups "Clojure" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to clojure+unsubscr...@googlegroups.com. >>>> >>>> For more options, visit https://groups.google.com/groups/opt_out. >>>> >>>> >>>> >>> >>> >>> >>> -- >>> Kornelis Sietsma korny at my surname dot com http://korny.info >>> .fnord { display: none !important; } >>> >>> -- >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clojure@googlegroups.com >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> To unsubscribe from this group, send email to >>> clojure+unsubscr...@googlegroups.com >>> For more options, visit this group at >>> http://groups.google.com/group/clojure?hl=en >>> --- >>> You received this message because you are subscribed to a topic in the >>> Google Groups "Clojure" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/clojure/D2OBBPTxGfY/unsubscribe?hl=en. >>> To unsubscribe from this group and all its topics, send an email to >>> clojure+unsubscr...@googlegroups.com. >>> For more options, visit https://groups.google.com/groups/opt_out. >>> >>> >>> >> >> -- >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/groups/opt_out. >> >> >> > -- > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to a topic in the > Google Groups "Clojure" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/clojure/D2OBBPTxGfY/unsubscribe?hl=en. > To unsubscribe from this group and all its topics, send an email to > clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/groups/opt_out. > > > -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.