Re: Struggling with encapsulation

2013-05-10 Thread Timo Mihaljov
On 10.05.2013 14:44, John D. Hume wrote: > 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 sev

Re: Struggling with encapsulation

2013-05-10 Thread Colin Yates
I get your point, but Java's LinkedBlockingQueue is mutable. Of course, I should replace it with a plain sequence or Clojure's persistent queue but I really want the blocking semantics. That's tomorrow's job :). On 10 May 2013 15:37, Jim - FooBar(); wrote: > On 10/05/13 14:20, Colin Yates wr

Re: Struggling with encapsulation

2013-05-10 Thread Jim - FooBar();
On 10/05/13 14:20, Colin Yates wrote: This is all about changing my mindset from 15-odd years of Java dev by learning from others, so let's give it a go. Years of enterprise Java dev have gotten their cynical, 'data is precious and should be hidden away', 'other devs will do the wrong thing' e

Re: Struggling with encapsulation

2013-05-10 Thread Colin Yates
On 10 May 2013 14:10, James Reeves wrote: > Have you tried it? :) > > I've authored about 40 Clojure libraries over 5 years, some with data > structures with internal components. The number of times someone has said > "I did X to this internal data and it broke" is exactly zero. It's never > ever

Re: Struggling with encapsulation

2013-05-10 Thread James Reeves
On 10 May 2013 11:32, Colin Yates wrote: > And please don't think I am making the 'code should stop bad programmers > doing the wrong thing' argument, I'm not (been there, lost). I just know > that if I released a scheduler library and the main construct was a map > containing a LBQ (or in fact

Re: Struggling with encapsulation

2013-05-10 Thread John D. Hume
The add method that you partially apply in new-scheduler should be private, because a user can't supply the first argument it expects. You might do something like this. (defn- add* [queue item] (...)) (defn add [scheduler item] ((scheduler :add) item)) (defn new-scheduler [] (let [queue (...

Re: Struggling with encapsulation

2013-05-10 Thread Colin Yates
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

Re: Struggling with encapsulation

2013-05-10 Thread John D. Hume
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-sched

Re: Struggling with encapsulation

2013-05-10 Thread Colin Yates
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

Re: Struggling with encapsulation

2013-05-10 Thread Korny Sietsma
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. Fu

Re: Struggling with encapsulation

2013-05-10 Thread Colin Yates
Hi James - thanks for your response. I am still trying to wrap my head around this as I cannot agree. To re-frame, woobly allows you to add a job. The internal implementation of this is that it is decorates that job and puts the *decorated job* onto an internal LBQ. The implementation also depe

Re: Struggling with encapsulation

2013-05-09 Thread James Reeves
On 9 May 2013 18:03, Colin Yates wrote: > 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

Re: Struggling with encapsulation

2013-05-09 Thread Colin Yates
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 lat

Re: Struggling with encapsulation

2013-05-09 Thread James Reeves
On 9 May 2013 17:07, Colin Yates 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 map

Re: Struggling with encapsulation

2013-05-09 Thread Dave Ray
I agree that you probably don't need to go overboard with hiding stuff. For option 2 though there's no need for deftype. Just implement the protocol with reifiy within the create function and use the closure for state. (defn create-woobly [...] (let [... put your queues and stuff here ...]

Re: Struggling with encapsulation

2013-05-09 Thread Jonathan Fischer Friberg
I agree with Gary, there's normally not really any need to obfuscate the implementation, and using the underlying structure can sometimes be useful. That said, if you really want to, you can create a "woobly" protocol and implement it using reify, this will make the underlying implementation compl

Re: Struggling with encapsulation

2013-05-09 Thread Gary Trakhman
If the interface provides everything that's needed, then there will be no need to dive in? I find attempts to hide that stuff frustrating when I'm a consumer of the code, if I need it, and I acknowledge that implementation details are subject-to-change when I take that risk, so only having somethi

Struggling with encapsulation

2013-05-09 Thread Colin Yates
(newbie, but trying hard!) I am designing a Woobly. A Woobly is non-trivial and has a number of internal data structures (queues, worker threads etc.). You can 'add' and 'remove' jobs from a Woobly. In OO land I might have a Woobly interface with the various methods which provides a public A