Finally beginning to dip my feet into the fascinating world of functional reactive programming. I come from a React-Redux background and want to try and implement some of the patterns I am familiar with there in a more pure FRP context. I am beginning to form some understanding of the nature and distinction between events and behaviors; questions like
- What's the difference between Behavior and Event in FRP?,
- FRP - Event streams and Signals - what is lost in using just signals? (where "signal" seems at least somewhat semantically similar to behavior), and
- Specification for a Functional Reactive Programming language
have been helpful in this regard.
However, I am still very much a novice in these waters, and have a specific question that I am not sure these posts answer. (They might, and I might just be a bit "slow on the uptake," as they say) - I want to be able to react to an event when in conjunction with a particular value of a given behavior. I suppose another way of saying this, as I've indicated by the title, is that I want to know if and how this would work -
Event * Behavior -> Event
For example, in React-Redux, I might have an items list backed by some remote API fetch. I would have an InitializeAction
get dispatched and reduced, resulting in an isLoading
flag being updated in the current state (behavior - at this point in time, the items are loading); as well as the effectful reaction of the API fetch being initiated (event - which, being handled, results in the fetch). One way I could implement this is by merely watching isLoading
and when it changes from false
to true
, initiate the fetch. So for example, connect
a component's props to to isLoading
and initiate the fetch out of that component's componentDidUpdate
method.
However, this method is not quite what I am attempting to find. I suppose in a sense the state change could be made out as an event being the product of the InitializeAction
event and the isLoading
behavior, but merely observing the change in isLoading
does not necessarily indicate the cause, merely the effect. This is nothing more than the formal logical fallacy of Affirming the Consequent, and would not help me if, say, some other action could also cause isLoading
to transition from false
to true
. I want to have a specific LoadItems
event generated specifically as a result of this specific InitializeAction
event when the state is specifically isLoading == false
.
The way I've handled this in React-Redux is to throw in the redux-loop middleware, which allows declarative effects to be an additional result from the reducer, as well as the updated state. So when isLoading == false
, and InitializeAction
occurs, the reducer's result is isLoading
changing from false
to true
, as well as a (pure, as yet unevaluated) API-fetch effect declaration. The middleware then returns only the canonical updated state to Redux and executes the effect. I like this approach, it's easy to reason about, and one of the best attempts at managing effects in a pure way, declaratively. If, as I am given to believe, one of FRP's strengths is capably handling effects, I would be very interested to see how it handles this kind of situation.
Sorry for the essay. I am new to this subject and so my ability to articulate the issue likely leaves much to be desired. Any help would be greatly appreciated.
Edit for clarification
This is what I want. Event emitter A
emits an Action event e_a
. Behavior subject S
with state b_t
at time t
computes, emits, stores the next state b_(t+1)
. Another event emitter F
emits an eFfect event e_f
that gets emitted when e_a
is emitted while b_t
is the current state. Both the updated state and the effect event can be subscribed to.
S=b_t <------
| |
v |
A --e_a--> + --b_(t+1)-->...
|
v
F --e_f-->...