Closed hanshoglund closed 8 years ago
Alas, this issue is much more profound than it might seem at first.
First, I'd like to remark that the IO
monad in MonadIO
is an implementation detail and will be replaced by a more specialized Moment
monad in a future version. In other words, the type signatures will read
accumE :: MonadMoment m => a -> Event (a -> a) -> m (Event a)
perhaps with a different name for the monad.
However, the fact that the three combinators return their event in a monad rather than as a plain value is hard to avoid. The main reason is that in the presence of dynamic event switching, some way to indicate starting times is required to avoid time leaks. Reactive-banana chooses a type parameter, but in the context of GUI programming, this would mean that every widget type has to be tagged with its time of creation, which seems prohibitively verbose as we would have to write an extra parameter Element t
all the time. That's why Threepenny has opted to use a monad instead.
Thanks for the elaboration. I would be happy with a non-IO type (including MonadIO and the like) wrapping the accumulators. You don't say what MonadMoment is, so I hope it will be something denotational.
I feel this issue is at heart of how FRP should be approached. I agree with you that time leaks are something that should be approach statically, but how still seems like an open question. As you say, restricting the accumulators is one way, restricting switcher
is another. Maybe there are more?
I think the general view nowadays (and the accepted implementation in reactive-banana
and other libraries) is that past-dependent events/behaviors must be defined in a monad if switching is allowed (is there a paper that describes this insight?).
Anyway, closing this.
This issue is to argue against the current design of
Reactive.Threepenny
.My objection is against the use of
MonadIO
in the accumulating methods, specifically the definition ofaccumE
andaccumB
(andstepper
andmapAccum
which can be defined in terms of the former two functions).I argue that these functions should be defined as follows (which is of course the definition used in
reactive
,reactive-banana
andreenact
– not insodium
), or removed.The rationale is the usual rant. IO breaks abstraction as we all know. The precense of IO (in the guise of
MonadIO m => m
) is an abstraction leak.I understand that there is a real-world compromise rationale for this API, but this in my view is a non-solution. I would go so far as to argue that the presence of these combinators ruin the (otherwise considerable) attractiveness of
threepenny-gui
as a simple, portable and functional GUI library.