Hi Jonah,

This sounds very much like the model layer in DDD, which ironically is
exactly what I am building.

However, in the middle of a data flow a function needs to reach out to
a repository to make a decision - how does that fit in with the data
flow approach?


On 5 March 2015 at 13:39, Jonah Benton <[email protected]> wrote:
> Hi Colin,
>
> Another option, other than HOFs or dynamic binding, is what might be called
> a data flow approach.
>
> At the edge of the application are the functions that explicitly take
> parameterized resources to perform edge state IO. These might be bare
> functions, or they might be protocol implementations that await the delivery
> of a type to perform their operation, or multimethods.
>
> At the center are functions that take a context map, which contains all
> relevant application state- IO resources and transient state data. Those
> functions are arranged in a data flow and capture the logic or state
> transitions of the application independent of any specific IO commitments.
> They can use schema or type annotation or pre/post conditions to enforce
> invariants.
>
> When data flow processing arrives at a place where some edge IO should
> occur, these data flow functions act as adapters to get-in the appropriate
> resource or Record from the context map and call the edge functions to
> perform IO.
>
> The result is a wider, flatter system, propagating state explicitly rather
> than implicitly through the call stack.
>
> Jonah
>
>
>
> On Wed, Mar 4, 2015 at 12:58 PM, Colin Yates <[email protected]> wrote:
>>
>> Hi,
>>
>> I am looking for the Clojure equivalent of:
>>
>> class Whatever {
>>     @Transactional
>>     void doSomething(IDoSomething one, IDoSomethingElse two) {
>>       one.doSomething()
>>       two.doSomething()
>>     }
>> }
>>
>> where both one and two are dependency injected with a proxy which resolves
>> to a thread local database connection. In addition, one might itself have a
>> collaborator which itself has a collaborator which needs a datasource.
>>
>> So far I have two protocols:
>>
>> (defprotocol IDoSomething
>>  (do-something [this ...])
>>
>> (defprotocol IDoSomethingElse
>>  (do-something [this ...])
>>
>> Each protocol may have a number of implementations, one of which is a JDBC
>> implementation:
>>
>> (defrecord JdbcIDoSomething [db]
>>   (do-something [this ...] ...))
>>
>> The problem is that the calling code only gets provided an IDoSomething
>> and an IDoSomethingElse and it wants to do something like:
>>
>> (let [one (->JdbcDoSomething db) two (->JdbcDoSomethingElse db)]
>>   (with-transaction [tx db]
>>     (do-something one)
>>     (do-something-else two)))
>>
>> The problem here is that the implementations of do-something and
>> do-something-else won't have access to the local bound 'tx', they will have
>> their own 'db'.
>>
>> I realise the general argument is to be explicit and pass a db as the
>> first argument to the protocol but this isn't appropriate in this case as
>> there are validly multiple implementations. I could abstract a
>> 'unit-of-work' and pass that as the first argument to the protocols but that
>> seems a bit painful.
>>
>> Also, these protocols may be used quite far away from where the database
>> code lives and passing a parameter all the way through the call stack is
>> painful.
>>
>> I am using Stuart Sierra's components if that makes any difference.
>>
>> I can't be the first person to run into this but google is surprisingly
>> unhelpful which makes me think I have missed something fundamental, and that
>> I have something upside down.
>>
>> What do you all do?
>>
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to [email protected]
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> [email protected]
>> 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 [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to [email protected]
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected].
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to