
Well, my impression is that trying to unite events and behaviours in this manner is not the solution we're looking for. If you follow the WWRD principle, you have to forget about events as fundamental building blocks, because the concept of event is an abstraction over continuous phenomena.
I'm not sure I want to follow WWRD all the way. I do want events, for example mouse clicks (for which there doesn't seem to be any logical behavior representation). As you note the pull-based approach does a lot more work in those cases than seems necessary. In any case, what I'm discussing in that report is mostly centered on the continuous-time values, so I'm more concerned with what we call behaviors. The question is how to model memory-full operations with point-wise operations. The only answer I've found for that in the Yampa framework is feedback with "pre", whose semantics seem to be the value after a "very short delay". This doesn't seem to hold water, when we really want to take the idea of continuous time seriously.
Reality has a trivial solution: throw extreme parallelism at the problem, set an extremely high sampling rate and shamelessly 'recalculate' unchanging parts of the system all the time (which is exactly why you don't want to use Yampa or Elerea for GUI programming: they are pull-based, so they'll keep the CPU churning even in the absence of events; note also that both solve the problem of unlimited access to the past). In this framework, events can only be introduced as high-level abstractions that require much more computational power than what would seem necessary. It is a bit like using a large and complex neural network to perform basic arithmetic.
Right. You'll agree that it would be nice to have a general approach? How will that work? That's what I'd like to find out.
Also, if you think about the applicative, monad etc. type class morphisms, you'll see that what makes sense for behaviours is completely useless for events. For instance, the applicative instance for behaviours (time functions) gives us a neat point-wise function application. However, if you define events as functions that are undefined almost everywhere, point-wise application of two events is only defined at the times where both events yield a value simultaneously. Same for monads: they capture the act of sampling for behaviours, but they can't do much for temporal values that are mostly undefined if interpreted as the reader monad. This suggests that events and behaviours have a different nature. Either only behaviours have a meaningful monad instance, or their meaningful monad instances are different.
Interesting points, I didn't consider that at all when writing that report. I'd like things to be unified, so maybe playing with the idea of a total function to 'Maybe a' for events is the right direction. I think this was already explored by some FRP incarnations, but I don't recall what came out of it.
The unified system you're describing very much reminds me of Lucid Synchrone, if we think of behaviours as signals synchronised to the base clock, while events as signals with a slower clock. It might be interesting to think about how clock calculus interacts with the type class instances. However, that still doesn't say anything about the fact that the set of operations meaningful for behaviours and events are different, with only some overlap.
But isn't Lucid Synchrone essentially discrete-timed? Also, events shouldn't be semantically constrained to multiples of some basic clock, they are defined over continuous time. Regarding the type classes - again I haven't thought in that direction much.
Gergely
P.S Thanks for the feedback!