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.


Reply via email to