[Haskell-cafe] Yampa vs. Reactive

Henrik Nilsson nhn at Cs.Nott.AC.UK
Wed Dec 17 09:29:05 EST 2008

Thomas Davie wrote:

 > Advantages of Yampa:
 > • Just at the moment, slightly more polished.
 > • (maybe) harder to introduce space/time leaks.
 > Advantages of Reactive:
 > • More functional programming like -- doesn't require you to use
 >   arrows everywhere, and supports a nice applicative style.
 > • In very active development.
 > • Active community.

I have not used Reactive as such, but I did use "Classic FRP"
extensively, and as far as I know the setup is similar, even
if Reactive has a modern and more principled interface.

Based on my Classic FRP experience (which may be out of date, if so,
correct me), I'd say advantages of Yampa are:

   * More modular.

     Yampa's signal function type is explicitly parameterized on the
     input signal type. In Classic FRP and Reactive (as far as I know),
     the system input is implicitly connected to all signal functions
     (or behaviours) in the system.

     One consequence of this is that it there were issues with reusing
     Classical FRP for different kinds of systems inputs, and difficult
     to combine systems with  different kinds of input. This was what
     prompted a parameterization on the type of the system input in the
     first place, which eventually led to Arrowized FRP and Yampa.

     I don't know what the current story of Reactive is in this respect.
     But having parameterized input has been crucial for work on big,
     mixed-domain, applications. (For example, a robot simulator with an
     interactive editor for setting up "the world". The robots were
     FRP systems too, but their input is naturally of a different kind
     that the overall system input. It also turned out to be very useful
     to have an FRP preprocessor for the system input, which then was
     composed with the rest of the system using what effectively was
     arrow composition (>>>), but called something else at the time.)

   * A clear separation between signals, signal functions, and ordinary
     functions and values, yet the ability to easily integrate all kinds
     of computations.

     Arguably a matter of taste, and in some ways more a consequence of
     the Arrow syntax than Arrows themselves. But in Classical FRP,
     one had to do either a lot of explicit lifting (in practice, we
     often ended up writing lifting wrappers for entire libraries), or
     try to exploit overloading for implicit lifting. The latter is
     quite limited though, partly due to how Haskell's type classes
     are organized and that language support for overloaded constants
     is limited to numerical constants.

     In any case, when we switched to arrows and arrow syntax, I found
     it liberating to not have to lift "everything" to signal functions
     first, but that I could program both with signals and signal
     functions on the one hand, and plain values and functions on the
     other, at the same time and fairly seamlessly. And personally,
     I also felt this made the programs conceptually clearer and easier
     to understand,

     My understanding is that Reactive is similar to Classical FRP in
     this respect.

   * Classical FRP lacked a satisfying approach to handle dynamic
     collections of reactive entities as needed when programming
     typical video games for example. Yampa has a way. One can
     argue about how satisfying it is, but at least it fulfills
     basic requirements such that allowing logically removed entities to
     be truly removed (garbage collected).

     I don't know where Reactive stands here.

   * There was also an issue with Classical FRP having to do with the
     need to observe the output from one part of the system in
     another part of the system. This is quite different from
     parameterizing the second part of the the system on the first,
     as this approach loses sharing across switches. This led to the
     development for "running in" constructs, which effectively
     made it possible for behaviours to be both signals (i.e.
     signal functions already applied to the system input),
     and signal functions (not yet applied to the system input).

     Yet there was no distinction between these "running behaviours"
     (= signals) and normal behaviours (= signal functions) at the
     type level. The approach also led to semantic difficulties, and,
     when trying to resolve those, to a very complicated design
     involving complicated overloading and auxiliary classes.

     The arrows approach obviated the need for all of this, and
     I consider that and other distinct advantage.

     Again, I don't know where Reactive stands here, but it needs to
     have a good answer to this issue, or it is going to suffer from
     limited expressivity.

Many of the above advantages are matters of opinion (but so are the
advantages initially put forward for Reactive above). However,
the development of AFRP and Yampa was motivated by fundamental
expresssivity limitations of Classical FRP, in at least some ways
related to the very way the system was set up. To the extent Reactive
is similar in style to Classical FRP, I think Reactive also needs to
address those questions.

All the best,


Henrik Nilsson
School of Computer Science
The University of Nottingham
nhn at cs.nott.ac.uk

This message has been checked for viruses but the contents of an attachment
may still contain software viruses, which could damage your computer system:
you are advised to perform your own checks. Email communications with the
University of Nottingham may be monitored as permitted by UK legislation.

More information about the Haskell-Cafe mailing list