Yes, exactly.

That's fine, a node in the "middle" of the data flow can be responsible for
reaching out to the edge to synchronously get some data to feed into a
decision performed by the data flow. It would just do that through the edge
functions.

A request for data could also be asynchronously initiated once enough
context had been determined by the data flow, and a promise added to the
context map for later derefing (likely with a timeout).

If the request for the data is context-free, it could be pulled in at the
start of the data flow.

By edge, it's is not that IO can't be done in the middle of a dataflow,
it's just that functions that deal with dataflow follow one pattern (taking
a context map) so they can be easily composed and rearranged, while
functions that deal with edge resources take those resources along with
other parameters more explicitly, so the data flow can run in an insulated
fashion.



On Thu, Mar 5, 2015 at 8:55 AM, Colin Yates <colin.ya...@gmail.com> wrote:

> 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 <jo...@jonah.com> 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 <colin.ya...@gmail.com>
> 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 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/d/optout.
> >
> >
> > --
> > 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/d/optout.
>
> --
> 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/d/optout.
>

-- 
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/d/optout.

Reply via email to