Re: functional thinking

2010-12-03 Thread ka
Hi Michael,

We're in a very similar situation to yours. Here's what we did:

1. 2 back end storage impls rah.storage1, rah.storage2 - these are
"private" nses.
2. a single storage interface rah.storage for the rest of the business
code. At runtime this decides which of storage1 or 2 to call.
3. Now you can implement 2. in many ways, protocol, multimethods,
global vars etc. We chose multimethods + macros to generate defmethod
calls automatically.

@ Laurent, Ken,
Why not wrap the entry point in bound-fn ? Convenience?

-- 
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


Re: functional thinking

2010-12-02 Thread Michael Ossareh
On Wed, Dec 1, 2010 at 10:51, Alyssa Kwan  wrote:

> Hi Mike,
>
> "TDD as if you meant it" -
>
> http://gojko.net/2009/02/27/thought-provoking-tdd-exercise-at-the-software-craftsmanship-conference/
>
> What you want is mocking and stubbing (these are different things!).
>
> http://s-expressions.com/2010/01/24/conjure-simple-mocking-and-stubbing-for-clojure-unit-tests/


Great links - thanks Alyssa.


>
>
> Remember that unit testing is NOT integration testing...
>
> Thanks,
> Alyssa
>
> On Dec 1, 8:29 am, Laurent PETIT  wrote:
> > Hi,
> >
> > 2010/12/1 Michael Ossareh 
> >
> > > Hi All,
> >
> > > In the course of putting together my latest piece of work I decided to
> > > really embrace TDD. This is run of the mill for me in Java:
> >
> > > - create some object that models your flow
> > > - create some object which contains your storage logic
> > > - create tests
> > > - dependency inject the correct storage logic depending on which
> scenario
> > > you're running in (prod / test / etc).
> >
> > Hum, this process does not seem to be eligible to be named "TDD". In TDD,
> > the tests are written first and "shape" the interface of your solution.
> Here
> > what to do is more "traditional": you write your domain objects, your
> logic,
> > and you add tests.
> > Not a critic of the methodology (I'm not advocating any methodology over
> > another here, to be clear), but rather a thought on how things are named.
> >
> > Some more thoughts (not sure they will help, but who knows ?) :
> >
> > > I've not been able to think about how to correctly achieve this same
> > > functionality in clojure.
> >
> > > So far everything is pretty much pure functions, the storage functions
> > > being the only place where data is changed. Currently the storage is
> > > implemented with atomic maps. The production storage will be in Riak.
> >
> > Hmm, if by "storage functions being the only place where data is changed"
> > you mean that in storage functions you do 2 things: change the value and
> > store them, then IMHO you could split them in 2.
> >
> >
> >
> >
> >
> > > I'm getting ready to build the Riak backend and now I'm faced with how
> to
> > > choose the correct backing implementation. I've a namespace,
> > > rah.test-storage, which implements the in-memory storage and I
> anticipate
> > > putting riak storage in rah.riak-storage - however I'm not sure what
> the
> > > best way to select the correct implementation at runtime or test time
> is.
> >
> > > One solution I've come up with is to use defprotocol to define the
> > > functions for the storage layer (as you would an interface in java) and
> then
> > > have a defrecord for each implementation. Assume these to be in the
> > > namespace rah.storage, which would also house the functions which call
> the
> > > correct defrecord functions based on a property given at start time.
> >
> > > This solution, however, feels like me trying to write Java in clojure -
> and
> > > I'm wondering how the lispers of the world would solve this same issue.
> >
> > > Another solution would be to write the same set of functions in the
> > > rah.storage namespace which then look at the same property and then
> decide
> > > whether to call rah.riak-storage/store-user! or
> > > rah.test-storage/store-user!.
> >
> > The solution, as every solution, will have to be a trade-of.
> > Here one "axis" for the tradeoff can be seen as "how powerful you want
> your
> > backend connectivity to be (singleton backend per app ? possibly several
> > different backends at the same time ? pluggable backends during runtime
> ?)
> > versus the ease of writing the app (the more probability you want power,
> the
> > more probability there will be to have a "backend" object to be passed
> > around : no backend object in case of a singleton backend for the app,
> > several singleton backend objects). Note that if you know that each
> > singleton backend will be of a "different kind" than the others, then
> simply
> > a keyword for representing each backend may be sufficient.
> >
> > From what I can infer from what you described, if you would write the
> > application without caring about programmatic testing, you would be fine
> by
> > just having top level functions, and probably a top level configuration
> map
> > with key/values for backend location, credentials, etc.
> >
> > If so, then it may be sufficient to leverage the possibility, in your
> > testing "framework" (clojure.test ? anything else ...) to redefine the
> > functions of the backend before the tests run. I'm pretty sure there are
> > already such features allowing to temporarily "redef" (and "restore" at
> the
> > end) the root value of global vars.
> >
> > HTH,
> >
> > --
> > Laurent- Hide quoted text -
> >
> > - Show quoted text -
>
> --
> 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 - pl

Re: functional thinking

2010-12-02 Thread Michael Ossareh
On Wed, Dec 1, 2010 at 05:29, Laurent PETIT  wrote:

> Hi,
>
> 2010/12/1 Michael Ossareh 
>
> Hi All,
>>
>> In the course of putting together my latest piece of work I decided to
>> really embrace TDD. This is run of the mill for me in Java:
>>
>> - create some object that models your flow
>> - create some object which contains your storage logic
>> - create tests
>> - dependency inject the correct storage logic depending on which scenario
>> you're running in (prod / test / etc).
>>
>>
> Hum, this process does not seem to be eligible to be named "TDD". In TDD,
> the tests are written first and "shape" the interface of your solution. Here
> what to do is more "traditional": you write your domain objects, your logic,
> and you add tests.
> Not a critic of the methodology (I'm not advocating any methodology over
> another here, to be clear), but rather a thought on how things are named.
>

Fair point. I do use TDD, I have no idea why I listed these steps
incorrectly! /me slaps his wrists.



>
> Some more thoughts (not sure they will help, but who knows ?) :
>
>
>> I've not been able to think about how to correctly achieve this same
>> functionality in clojure.
>>
>> So far everything is pretty much pure functions, the storage functions
>> being the only place where data is changed. Currently the storage is
>> implemented with atomic maps. The production storage will be in Riak.
>>
>
> Hmm, if by "storage functions being the only place where data is changed"
> you mean that in storage functions you do 2 things: change the value and
> store them, then IMHO you could split them in 2.
>

Storage functions here mean taking the data given to them and storing them -
they do not change the data that they receive.


>
>
>> I'm getting ready to build the Riak backend and now I'm faced with how to
>> choose the correct backing implementation. I've a namespace,
>> rah.test-storage, which implements the in-memory storage and I anticipate
>> putting riak storage in rah.riak-storage - however I'm not sure what the
>> best way to select the correct implementation at runtime or test time is.
>>
>> One solution I've come up with is to use defprotocol to define the
>> functions for the storage layer (as you would an interface in java) and then
>> have a defrecord for each implementation. Assume these to be in the
>> namespace rah.storage, which would also house the functions which call the
>> correct defrecord functions based on a property given at start time.
>>
>> This solution, however, feels like me trying to write Java in clojure -
>> and I'm wondering how the lispers of the world would solve this same issue.
>>
>> Another solution would be to write the same set of functions in the
>> rah.storage namespace which then look at the same property and then decide
>> whether to call rah.riak-storage/store-user! or
>> rah.test-storage/store-user!.
>>
>
> The solution, as every solution, will have to be a trade-of.
> Here one "axis" for the tradeoff can be seen as "how powerful you want your
> backend connectivity to be (singleton backend per app ? possibly several
> different backends at the same time ? pluggable backends during runtime ?)
> versus the ease of writing the app (the more probability you want power, the
> more probability there will be to have a "backend" object to be passed
> around : no backend object in case of a singleton backend for the app,
> several singleton backend objects). Note that if you know that each
> singleton backend will be of a "different kind" than the others, then simply
> a keyword for representing each backend may be sufficient.
>

This keyword for different backend concept is amazing. Thank you! It reminds
me a little of how pallet  achieves it's
shiz. I'll ensure to read up on it does what it does.



>
> From what I can infer from what you described, if you would write the
> application without caring about programmatic testing, you would be fine by
> just having top level functions, and probably a top level configuration map
> with key/values for backend location, credentials, etc.
>
> If so, then it may be sufficient to leverage the possibility, in your
> testing "framework" (clojure.test ? anything else ...) to redefine the
> functions of the backend before the tests run. I'm pretty sure there are
> already such features allowing to temporarily "redef" (and "restore" at the
> end) the root value of global vars.
>

Laurent, thanks so much. This is really great.

Cheers,

mike


>
> HTH,
>
> --
> Laurent
>
>
>
> --
> 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 th

Re: functional thinking

2010-12-01 Thread trptcolin
On Dec 1, 3:33 pm, Ken Wesson  wrote:
> On Wed, Dec 1, 2010 at 9:38 AM, Laurent PETIT  wrote:
> > 2010/12/1 Ken Wesson 
>
> >> On Wed, Dec 1, 2010 at 8:29 AM, Laurent PETIT 
> >> wrote:
> >> > If so, then it may be sufficient to leverage the possibility, in your
> >> > testing "framework" (clojure.test ? anything else ...) to redefine the
> >> > functions of the backend before the tests run. I'm pretty sure there are
> >> > already such features allowing to temporarily "redef" (and "restore" at
> >> > the
> >> > end) the root value of global vars.
>
> >> (binding [*global-var* temp-value]
> >>  (run-some-tests))
>
> >> :)
>
> > I didn't forget it. But :
> >   * in Clojure 1.2 : these binding do not automatically flow from thread to
> > thread, so they do not work "in the general case" (though arguably this
> > general case may not be the usual case)
> >   * in Clojure 1.3 : the bindings will now flow from thread to thread when
> > using clojure primitives (agents, futures, pmap, etc.), *but* the default
> > for vars will change from dynamic rebindable to not dynamic rebindable
> > (dynamic rebindability will have to be explicit)
>
> > :)
>
> If you need it in multiple threads, you're just gonna have to go with
> the slightly evil
>
> (let [x *foo*]
>   (alter-var-root #'*foo* (constantly testing-value))
>   (do-some-tests)
>   (alter-var-root #'*foo* (constantly x)))

There's actually a shortcut for this in 1.3.0-alpha3, thanks to Chris
Houser and Stuart Halloway:

(with-redefs [*foo* (constantly testing-value)]
  (do-some-tests))

-Colin

-- 
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


Re: functional thinking

2010-12-01 Thread Laurent PETIT
2010/12/1 Ken Wesson 

> On Wed, Dec 1, 2010 at 9:38 AM, Laurent PETIT 
> wrote:
> > 2010/12/1 Ken Wesson 
> >>
> >> On Wed, Dec 1, 2010 at 8:29 AM, Laurent PETIT 
> >> wrote:
> >> > If so, then it may be sufficient to leverage the possibility, in your
> >> > testing "framework" (clojure.test ? anything else ...) to redefine the
> >> > functions of the backend before the tests run. I'm pretty sure there
> are
> >> > already such features allowing to temporarily "redef" (and "restore"
> at
> >> > the
> >> > end) the root value of global vars.
> >>
> >> (binding [*global-var* temp-value]
> >>  (run-some-tests))
> >>
> >> :)
> >>
> >>
> >
> > I didn't forget it. But :
> >   * in Clojure 1.2 : these binding do not automatically flow from thread
> to
> > thread, so they do not work "in the general case" (though arguably this
> > general case may not be the usual case)
> >   * in Clojure 1.3 : the bindings will now flow from thread to thread
> when
> > using clojure primitives (agents, futures, pmap, etc.), *but* the default
> > for vars will change from dynamic rebindable to not dynamic rebindable
> > (dynamic rebindability will have to be explicit)
> >
> > :)
>
> If you need it in multiple threads, you're just gonna have to go with
> the slightly evil
>
> (let [x *foo*]
>  (alter-var-root #'*foo* (constantly testing-value))
>  (do-some-tests)
>  (alter-var-root #'*foo* (constantly x)))
>
>

Yes, that's more or less what I was suggesting, and is, I think, implemented
somehow in mocking test libraries, probably with a guarding try/finally.

-- 
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

Re: functional thinking

2010-12-01 Thread Ken Wesson
On Wed, Dec 1, 2010 at 9:38 AM, Laurent PETIT  wrote:
> 2010/12/1 Ken Wesson 
>>
>> On Wed, Dec 1, 2010 at 8:29 AM, Laurent PETIT 
>> wrote:
>> > If so, then it may be sufficient to leverage the possibility, in your
>> > testing "framework" (clojure.test ? anything else ...) to redefine the
>> > functions of the backend before the tests run. I'm pretty sure there are
>> > already such features allowing to temporarily "redef" (and "restore" at
>> > the
>> > end) the root value of global vars.
>>
>> (binding [*global-var* temp-value]
>>  (run-some-tests))
>>
>> :)
>>
>>
>
> I didn't forget it. But :
>   * in Clojure 1.2 : these binding do not automatically flow from thread to
> thread, so they do not work "in the general case" (though arguably this
> general case may not be the usual case)
>   * in Clojure 1.3 : the bindings will now flow from thread to thread when
> using clojure primitives (agents, futures, pmap, etc.), *but* the default
> for vars will change from dynamic rebindable to not dynamic rebindable
> (dynamic rebindability will have to be explicit)
>
> :)

If you need it in multiple threads, you're just gonna have to go with
the slightly evil

(let [x *foo*]
  (alter-var-root #'*foo* (constantly testing-value))
  (do-some-tests)
  (alter-var-root #'*foo* (constantly x)))

-- 
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


Re: functional thinking

2010-12-01 Thread Laurent PETIT
 Note, though, that he did not use the words "unit testing", you did :)

And mocking and stubbing are techniques that can be done at different scales
...

2010/12/1 Alyssa Kwan 

> Hi Mike,
>
> "TDD as if you meant it" -
>
> http://gojko.net/2009/02/27/thought-provoking-tdd-exercise-at-the-software-craftsmanship-conference/
>
> What you want is mocking and stubbing (these are different things!).
>
> http://s-expressions.com/2010/01/24/conjure-simple-mocking-and-stubbing-for-clojure-unit-tests/
>
> Remember that unit testing is NOT integration testing...
>
> Thanks,
> Alyssa
>
> On Dec 1, 8:29 am, Laurent PETIT  wrote:
> > Hi,
> >
> > 2010/12/1 Michael Ossareh 
> >
> > > Hi All,
> >
> > > In the course of putting together my latest piece of work I decided to
> > > really embrace TDD. This is run of the mill for me in Java:
> >
> > > - create some object that models your flow
> > > - create some object which contains your storage logic
> > > - create tests
> > > - dependency inject the correct storage logic depending on which
> scenario
> > > you're running in (prod / test / etc).
> >
> > Hum, this process does not seem to be eligible to be named "TDD". In TDD,
> > the tests are written first and "shape" the interface of your solution.
> Here
> > what to do is more "traditional": you write your domain objects, your
> logic,
> > and you add tests.
> > Not a critic of the methodology (I'm not advocating any methodology over
> > another here, to be clear), but rather a thought on how things are named.
> >
> > Some more thoughts (not sure they will help, but who knows ?) :
> >
> > > I've not been able to think about how to correctly achieve this same
> > > functionality in clojure.
> >
> > > So far everything is pretty much pure functions, the storage functions
> > > being the only place where data is changed. Currently the storage is
> > > implemented with atomic maps. The production storage will be in Riak.
> >
> > Hmm, if by "storage functions being the only place where data is changed"
> > you mean that in storage functions you do 2 things: change the value and
> > store them, then IMHO you could split them in 2.
> >
> >
> >
> >
> >
> > > I'm getting ready to build the Riak backend and now I'm faced with how
> to
> > > choose the correct backing implementation. I've a namespace,
> > > rah.test-storage, which implements the in-memory storage and I
> anticipate
> > > putting riak storage in rah.riak-storage - however I'm not sure what
> the
> > > best way to select the correct implementation at runtime or test time
> is.
> >
> > > One solution I've come up with is to use defprotocol to define the
> > > functions for the storage layer (as you would an interface in java) and
> then
> > > have a defrecord for each implementation. Assume these to be in the
> > > namespace rah.storage, which would also house the functions which call
> the
> > > correct defrecord functions based on a property given at start time.
> >
> > > This solution, however, feels like me trying to write Java in clojure -
> and
> > > I'm wondering how the lispers of the world would solve this same issue.
> >
> > > Another solution would be to write the same set of functions in the
> > > rah.storage namespace which then look at the same property and then
> decide
> > > whether to call rah.riak-storage/store-user! or
> > > rah.test-storage/store-user!.
> >
> > The solution, as every solution, will have to be a trade-of.
> > Here one "axis" for the tradeoff can be seen as "how powerful you want
> your
> > backend connectivity to be (singleton backend per app ? possibly several
> > different backends at the same time ? pluggable backends during runtime
> ?)
> > versus the ease of writing the app (the more probability you want power,
> the
> > more probability there will be to have a "backend" object to be passed
> > around : no backend object in case of a singleton backend for the app,
> > several singleton backend objects). Note that if you know that each
> > singleton backend will be of a "different kind" than the others, then
> simply
> > a keyword for representing each backend may be sufficient.
> >
> > From what I can infer from what you described, if you would write the
> > application without caring about programmatic testing, you would be fine
> by
> > just having top level functions, and probably a top level configuration
> map
> > with key/values for backend location, credentials, etc.
> >
> > If so, then it may be sufficient to leverage the possibility, in your
> > testing "framework" (clojure.test ? anything else ...) to redefine the
> > functions of the backend before the tests run. I'm pretty sure there are
> > already such features allowing to temporarily "redef" (and "restore" at
> the
> > end) the root value of global vars.
> >
> > HTH,
> >
> > --
> > Laurent- Hide quoted text -
> >
> > - Show quoted text -
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group,

Re: functional thinking

2010-12-01 Thread Alyssa Kwan
Hi Mike,

"TDD as if you meant it" -
http://gojko.net/2009/02/27/thought-provoking-tdd-exercise-at-the-software-craftsmanship-conference/

What you want is mocking and stubbing (these are different things!).
http://s-expressions.com/2010/01/24/conjure-simple-mocking-and-stubbing-for-clojure-unit-tests/

Remember that unit testing is NOT integration testing...

Thanks,
Alyssa

On Dec 1, 8:29 am, Laurent PETIT  wrote:
> Hi,
>
> 2010/12/1 Michael Ossareh 
>
> > Hi All,
>
> > In the course of putting together my latest piece of work I decided to
> > really embrace TDD. This is run of the mill for me in Java:
>
> > - create some object that models your flow
> > - create some object which contains your storage logic
> > - create tests
> > - dependency inject the correct storage logic depending on which scenario
> > you're running in (prod / test / etc).
>
> Hum, this process does not seem to be eligible to be named "TDD". In TDD,
> the tests are written first and "shape" the interface of your solution. Here
> what to do is more "traditional": you write your domain objects, your logic,
> and you add tests.
> Not a critic of the methodology (I'm not advocating any methodology over
> another here, to be clear), but rather a thought on how things are named.
>
> Some more thoughts (not sure they will help, but who knows ?) :
>
> > I've not been able to think about how to correctly achieve this same
> > functionality in clojure.
>
> > So far everything is pretty much pure functions, the storage functions
> > being the only place where data is changed. Currently the storage is
> > implemented with atomic maps. The production storage will be in Riak.
>
> Hmm, if by "storage functions being the only place where data is changed"
> you mean that in storage functions you do 2 things: change the value and
> store them, then IMHO you could split them in 2.
>
>
>
>
>
> > I'm getting ready to build the Riak backend and now I'm faced with how to
> > choose the correct backing implementation. I've a namespace,
> > rah.test-storage, which implements the in-memory storage and I anticipate
> > putting riak storage in rah.riak-storage - however I'm not sure what the
> > best way to select the correct implementation at runtime or test time is.
>
> > One solution I've come up with is to use defprotocol to define the
> > functions for the storage layer (as you would an interface in java) and then
> > have a defrecord for each implementation. Assume these to be in the
> > namespace rah.storage, which would also house the functions which call the
> > correct defrecord functions based on a property given at start time.
>
> > This solution, however, feels like me trying to write Java in clojure - and
> > I'm wondering how the lispers of the world would solve this same issue.
>
> > Another solution would be to write the same set of functions in the
> > rah.storage namespace which then look at the same property and then decide
> > whether to call rah.riak-storage/store-user! or
> > rah.test-storage/store-user!.
>
> The solution, as every solution, will have to be a trade-of.
> Here one "axis" for the tradeoff can be seen as "how powerful you want your
> backend connectivity to be (singleton backend per app ? possibly several
> different backends at the same time ? pluggable backends during runtime ?)
> versus the ease of writing the app (the more probability you want power, the
> more probability there will be to have a "backend" object to be passed
> around : no backend object in case of a singleton backend for the app,
> several singleton backend objects). Note that if you know that each
> singleton backend will be of a "different kind" than the others, then simply
> a keyword for representing each backend may be sufficient.
>
> From what I can infer from what you described, if you would write the
> application without caring about programmatic testing, you would be fine by
> just having top level functions, and probably a top level configuration map
> with key/values for backend location, credentials, etc.
>
> If so, then it may be sufficient to leverage the possibility, in your
> testing "framework" (clojure.test ? anything else ...) to redefine the
> functions of the backend before the tests run. I'm pretty sure there are
> already such features allowing to temporarily "redef" (and "restore" at the
> end) the root value of global vars.
>
> HTH,
>
> --
> Laurent- Hide quoted text -
>
> - Show quoted text -

-- 
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


Re: functional thinking

2010-12-01 Thread Laurent PETIT
2010/12/1 Ken Wesson 

> On Wed, Dec 1, 2010 at 8:29 AM, Laurent PETIT 
> wrote:
> > If so, then it may be sufficient to leverage the possibility, in your
> > testing "framework" (clojure.test ? anything else ...) to redefine the
> > functions of the backend before the tests run. I'm pretty sure there are
> > already such features allowing to temporarily "redef" (and "restore" at
> the
> > end) the root value of global vars.
>
> (binding [*global-var* temp-value]
>  (run-some-tests))
>
> :)
>
>
>
I didn't forget it. But :
  * in Clojure 1.2 : these binding do not automatically flow from thread to
thread, so they do not work "in the general case" (though arguably this
general case may not be the usual case)
  * in Clojure 1.3 : the bindings will now flow from thread to thread when
using clojure primitives (agents, futures, pmap, etc.), *but* the default
for vars will change from dynamic rebindable to not dynamic rebindable
(dynamic rebindability will have to be explicit)

:)

-- 
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

Re: functional thinking

2010-12-01 Thread Ken Wesson
On Wed, Dec 1, 2010 at 8:29 AM, Laurent PETIT  wrote:
> If so, then it may be sufficient to leverage the possibility, in your
> testing "framework" (clojure.test ? anything else ...) to redefine the
> functions of the backend before the tests run. I'm pretty sure there are
> already such features allowing to temporarily "redef" (and "restore" at the
> end) the root value of global vars.

(binding [*global-var* temp-value]
  (run-some-tests))

:)

-- 
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


Re: functional thinking

2010-12-01 Thread Laurent PETIT
Hi,

2010/12/1 Michael Ossareh 

> Hi All,
>
> In the course of putting together my latest piece of work I decided to
> really embrace TDD. This is run of the mill for me in Java:
>
> - create some object that models your flow
> - create some object which contains your storage logic
> - create tests
> - dependency inject the correct storage logic depending on which scenario
> you're running in (prod / test / etc).
>
>
Hum, this process does not seem to be eligible to be named "TDD". In TDD,
the tests are written first and "shape" the interface of your solution. Here
what to do is more "traditional": you write your domain objects, your logic,
and you add tests.
Not a critic of the methodology (I'm not advocating any methodology over
another here, to be clear), but rather a thought on how things are named.

Some more thoughts (not sure they will help, but who knows ?) :


> I've not been able to think about how to correctly achieve this same
> functionality in clojure.
>
> So far everything is pretty much pure functions, the storage functions
> being the only place where data is changed. Currently the storage is
> implemented with atomic maps. The production storage will be in Riak.
>

Hmm, if by "storage functions being the only place where data is changed"
you mean that in storage functions you do 2 things: change the value and
store them, then IMHO you could split them in 2.


> I'm getting ready to build the Riak backend and now I'm faced with how to
> choose the correct backing implementation. I've a namespace,
> rah.test-storage, which implements the in-memory storage and I anticipate
> putting riak storage in rah.riak-storage - however I'm not sure what the
> best way to select the correct implementation at runtime or test time is.
>
> One solution I've come up with is to use defprotocol to define the
> functions for the storage layer (as you would an interface in java) and then
> have a defrecord for each implementation. Assume these to be in the
> namespace rah.storage, which would also house the functions which call the
> correct defrecord functions based on a property given at start time.
>
> This solution, however, feels like me trying to write Java in clojure - and
> I'm wondering how the lispers of the world would solve this same issue.
>
> Another solution would be to write the same set of functions in the
> rah.storage namespace which then look at the same property and then decide
> whether to call rah.riak-storage/store-user! or
> rah.test-storage/store-user!.
>

The solution, as every solution, will have to be a trade-of.
Here one "axis" for the tradeoff can be seen as "how powerful you want your
backend connectivity to be (singleton backend per app ? possibly several
different backends at the same time ? pluggable backends during runtime ?)
versus the ease of writing the app (the more probability you want power, the
more probability there will be to have a "backend" object to be passed
around : no backend object in case of a singleton backend for the app,
several singleton backend objects). Note that if you know that each
singleton backend will be of a "different kind" than the others, then simply
a keyword for representing each backend may be sufficient.

>From what I can infer from what you described, if you would write the
application without caring about programmatic testing, you would be fine by
just having top level functions, and probably a top level configuration map
with key/values for backend location, credentials, etc.

If so, then it may be sufficient to leverage the possibility, in your
testing "framework" (clojure.test ? anything else ...) to redefine the
functions of the backend before the tests run. I'm pretty sure there are
already such features allowing to temporarily "redef" (and "restore" at the
end) the root value of global vars.

HTH,

-- 
Laurent

-- 
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

functional thinking

2010-12-01 Thread Michael Ossareh
Hi All,

In the course of putting together my latest piece of work I decided to
really embrace TDD. This is run of the mill for me in Java:

- create some object that models your flow
- create some object which contains your storage logic
- create tests
- dependency inject the correct storage logic depending on which scenario
you're running in (prod / test / etc).

I've not been able to think about how to correctly achieve this same
functionality in clojure.

So far everything is pretty much pure functions, the storage functions being
the only place where data is changed. Currently the storage is implemented
with atomic maps. The production storage will be in Riak.

I'm getting ready to build the Riak backend and now I'm faced with how to
choose the correct backing implementation. I've a namespace,
rah.test-storage, which implements the in-memory storage and I anticipate
putting riak storage in rah.riak-storage - however I'm not sure what the
best way to select the correct implementation at runtime or test time is.

One solution I've come up with is to use defprotocol to define the functions
for the storage layer (as you would an interface in java) and then have a
defrecord for each implementation. Assume these to be in the namespace
rah.storage, which would also house the functions which call the correct
defrecord functions based on a property given at start time.

This solution, however, feels like me trying to write Java in clojure - and
I'm wondering how the lispers of the world would solve this same issue.

Another solution would be to write the same set of functions in the
rah.storage namespace which then look at the same property and then decide
whether to call rah.riak-storage/store-user! or
rah.test-storage/store-user!.

Any thoughts much appreciated.

Cheers,

mike

-- 
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