+0.98 - 0.02 reserved whilst I get comfortable with "complexity in middleware" not falling into the same traps as AOP :).
On 3 April 2015 at 15:04, Daniel Kersten <dkers...@gmail.com> wrote: > So, thinking about this some more: > > If you treat the system as a state machine and the events as the state > transitions (which are performed by the handlers) and the db as the current > state (basically as described in the readme), then I think changing the > active player in the same handler as placing the players move actually makes > sense. > > However, rather than simply merging the two actions together, you could take > one of these approaches: > > (register-handler > :make-move > [(enrich change-to-next-player) with-player (path :game-board)] > (fn [board [_ cell player]] > (assoc board cell player))) > > Where change-to-next-player and with-player are defined as: > > (defn change-to-next-player [db] (assoc db :current-player ...)) > (defn with-player [handler] (fn [db v] (handler db (conj v (:current-player > db)))) > > That is, the handler only does one job and middleware is used to mix other > logic in. > > Alternatively: > > (register-handler > ;make-move > (after #(dispatch [:change-player])) > (fn [db [_ cell]] > (assoc-in db [:game-board cell] (:current-player db)))) > > That is, you have two handlers (one to make the move and one to change the > player), but the make move handler dispatches a change-player event using > the after middleware. > > In both approaches, the make-move is treated as a state transition which > moves from the (game-board, player1) state to the (new-game-board, player2) > state. > > I'm personally a big fan of using middleware to brush complexity under the > rug, so to say, keeping the actual handler pure and focused on a single task > (easy to test, easy to understand, potential for reuse). > For example, I'm currently experimenting with doing all server I/O and other > side-effecting logic through handler middleware and keeping my handlers > pure, subscriptions pure (in that they only rely on their db parameter; > technically I guess you could say they're not pure as they maintain watchers > and such), the components pure (again, with the caveat that they maintain > subscriptions). > > On Fri, 3 Apr 2015 at 14:44 Daniel Kersten <dkers...@gmail.com> wrote: >> >> The relevant code is here: >> https://github.com/Day8/re-frame/blob/master/src/re_frame/router.cljs#L30-L36 >> >> But yes, unless its specifically stated to be ordered, its probably best >> to treat it as an implementation detail and not rely on it. >> >> Somewhat off topic as it doesn't address Rafal's question: >> >> I once worked on a message system where I wanted handlers to run in >> parallel, but sometimes ordering (between a subset of the events) is >> important. So I implemented a "conversation" system, such that within a >> conversation, messages were strictly ordered, but multiple conversations >> could be parallel and/or interleaved and messages not part of a conversation >> were always unordered. Eg: (my-dispatch [:foo]) is unordered and >> (my-dispatch my-conversation [:foo]) is ordered with respect to other >> messages where my-conversation was set (and my-conversation is just a unique >> id of some kind). >> >> Perhaps a similar system could be built on top of re-frame. >> >> On Fri, 3 Apr 2015 at 13:29 Colin Yates <colin.ya...@gmail.com> wrote: >>> >>> Thanks for the clarification - I would still be nervous about relying >>> on the sequencing though as that feels like an implementation detail. >>> >>> I am concerned though about the interpretation of "Why? Partially >>> because handlers are given a snapshot of the app-db and can't be >>> nested.". This is still a little ambiguous for me - for example, if it >>> means nested in terms of transactions then it means the opposite of >>> what you think. >>> >>> The above could be read as "each handler is given the _same_ snapshot >>> of the database" in which case event dispatch sequence is irrelevant, >>> or "the db is the result of reducing each handler onto the snapshot". >>> I really should check the code (but head elsewhere ATM). >>> >>> On 3 April 2015 at 13:07, Daniel Kersten <dkers...@gmail.com> wrote: >>> > Right, I see what you mean. I think I need to think about it some more >>> > :) >>> > >>> > >>> > >>> > On Fri, 3 Apr 2015 at 12:58 Rafał Cieślak <ravici...@gmail.com> wrote: >>> >> >>> >> > That is, have the event control which player it gets applied to. >>> >> > This >>> >> > way the handler does not need any knowledge of this at all and can >>> >> > use path >>> >> > middleware to focus in on only what it cares about (the game board, >>> >> > in the >>> >> > case of selecting a cell). >>> >> >>> >> I think it's better to fetch the player in the handler, as the cell >>> >> component itself doesn't care about whose turn it is. >>> >> >>> >> But maybe your solution is more FRP-ish, I don't know. ;) >>> >> >>> >> -- >>> >> Note that posts from new members are moderated - please be patient >>> >> with >>> >> your first post. >>> >> --- >>> >> You received this message because you are subscribed to the Google >>> >> Groups >>> >> "ClojureScript" group. >>> >> To unsubscribe from this group and stop receiving emails from it, send >>> >> an >>> >> email to clojurescript+unsubscr...@googlegroups.com. >>> >> To post to this group, send email to clojurescript@googlegroups.com. >>> >> Visit this group at http://groups.google.com/group/clojurescript. >>> > >>> > -- >>> > Note that posts from new members are moderated - please be patient with >>> > your >>> > first post. >>> > --- >>> > You received this message because you are subscribed to the Google >>> > Groups >>> > "ClojureScript" group. >>> > To unsubscribe from this group and stop receiving emails from it, send >>> > an >>> > email to clojurescript+unsubscr...@googlegroups.com. >>> > To post to this group, send email to clojurescript@googlegroups.com. >>> > Visit this group at http://groups.google.com/group/clojurescript. >>> >>> -- >>> Note that posts from new members are moderated - please be patient with >>> your first post. >>> --- >>> You received this message because you are subscribed to the Google Groups >>> "ClojureScript" group. >>> To unsubscribe from this group and stop receiving emails from it, send an >>> email to clojurescript+unsubscr...@googlegroups.com. >>> To post to this group, send email to clojurescript@googlegroups.com. >>> Visit this group at http://groups.google.com/group/clojurescript. > > -- > Note that posts from new members are moderated - please be patient with your > first post. > --- > You received this message because you are subscribed to the Google Groups > "ClojureScript" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojurescript+unsubscr...@googlegroups.com. > To post to this group, send email to clojurescript@googlegroups.com. > Visit this group at http://groups.google.com/group/clojurescript. -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojurescript+unsubscr...@googlegroups.com. To post to this group, send email to clojurescript@googlegroups.com. Visit this group at http://groups.google.com/group/clojurescript.