Essential Reactive functions?

I'm building a little Reactive library in C# for fun - in the same spirit as Conal's one - with the intension to convert that to F#, which I'm learning now. Right now I implemented Future, Event and Reactive, and functionality to merge/mappend two events. Although I'm not yet sure it fully works, using some tricks from Reactive, it was actually really easy to implement. I don't need unamb stuff since I just spawn one new thread for each merged event, and I use the WaitForMultipleObjects primitive to check which of the two event occurrences was first. The code is of course a zillion times more ugly than in Haskell, and since I'm not using lightweight threads, it might really be slow. I tried to make it as immutable as possible, so it's not really imperative :) But what is the minimal set of functions one must implement to build a Reactive library, in the sense that all others can be implemented using these? Merry Xmas!

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Peter Verswyvelen wrote:
But what is the minimal set of functions one must implement to build a Reactive library, in the sense that all others can be implemented using these?
My in-progress FRP implementation is loosely based on Reactive. The semantics are essentially the same, although the interface is becoming a bit different, the implementation is completely different, and mine has some limitations (which I may decide to intentionally leave in) which Reactive does not. Keeping in mind that I haven't implemented all functionality yet, these are the functions I currently have which require unexported constructors and functions, ignoring some which have to do with my changed interface: * Functor Event functions * Monoid (Event a) functions * Functor Reactive functions * Applicative Reactive functions * Functor (Behavior t) functions * Applicative (Behavior t) functions * rToB :: Reactive a -> Behavior t a * accumE :: a -> Event (a -> a) -> Event a * stepper :: a -> Event a -> Reactive a * snapshot :: Event a -> Reactive b -> Event (a, b) * time :: Behavior t t * timeR -- a type specific to my interface * filterE :: (a -> Bool) -> Event a -> Event a * partitionE :: (a -> Bool) -> Event a -> (Event a, Event a) I plan to eventually separate these core functions from my derived functions into different modules, making these distinctions more clear. I also suspect that this set is not as minimal as it can be and will try to make it shorter in the future. I know this doesn't necessarily help you since mine is not really Reactive, but I thought perhaps it could give you at least an idea. - - Jake -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAklVCfwACgkQye5hVyvIUKkS1gCgscABZOLtz5AafRsI9hC8IbTF NJkAoMB5xQleVJc5R0hPMJ5NS+Gl2ShY =doca -----END PGP SIGNATURE-----

Hi Peter, I don't need unamb stuff since I just spawn one new thread for each merged
event, and I use the WaitForMultipleObjects primitive to check which of the two event occurrences was first.
By "was first", do you mean the occurrence itself or when it was detected?
The latter is easier to implement but disagrees with the semantics (see
http://conal.net/blog/posts/future-values-via-multi-threading/), which is
what eventually led me to unamb.
I don't know what it takes to create and use a FRP library with pure
semantics in a strict language (like C# and F#).
Since you're using WaitForMultipleObjects and working in strict languages,
you might find Mike Sperber's thesis helpful:
http://w210.ub.uni-tuebingen.de/dbt/volltexte/2001/266/pdf/lula-thesis.pdf.
He doesn't get the simple pure semantics of classic FRP or Reactive,
but
he does explore some of the complex issues of dealing with FRP in a strict
setting.
I'd love to hear how your experiment goes.
- Conal
2008/12/26 Peter Verswyvelen
I'm building a little Reactive library in C# for fun - in the same spirit as Conal's one - with the intension to convert that to F#, which I'm learning now. Right now I implemented Future, Event and Reactive, and functionality to merge/mappend two events.
Although I'm not yet sure it fully works, using some tricks from Reactive, it was actually really easy to implement. I don't need unamb stuff since I just spawn one new thread for each merged event, and I use the WaitForMultipleObjects primitive to check which of the two event occurrences was first. The code is of course a zillion times more ugly than in Haskell, and since I'm not using lightweight threads, it might really be slow. I tried to make it as immutable as possible, so it's not really imperative :)
But what is the minimal set of functions one must implement to build a Reactive library, in the sense that all others can be implemented using these?
Merry Xmas!

About your question of the essential functions, you can look at the modules
Reactive.PrimReactive and Reactive.Reactive in the Reactive package. The
former accesses representations, and the latter doesn't. The modules don't
make this clear split for behaviors.
- Conal
On Fri, Dec 26, 2008 at 11:01 AM, Conal Elliott
Hi Peter,
I don't need unamb stuff since I just spawn one new thread for each merged
event, and I use the WaitForMultipleObjects primitive to check which of the two event occurrences was first.
By "was first", do you mean the occurrence itself or when it was detected? The latter is easier to implement but disagrees with the semantics (see http://conal.net/blog/posts/future-values-via-multi-threading/), which is what eventually led me to unamb.
I don't know what it takes to create and use a FRP library with pure semantics in a strict language (like C# and F#).
Since you're using WaitForMultipleObjects and working in strict languages, you might find Mike Sperber's thesis helpful: http://w210.ub.uni-tuebingen.de/dbt/volltexte/2001/266/pdf/lula-thesis.pdf. He doesn't get the simple pure semantics of classic FRP or Reactive, but he does explore some of the complex issues of dealing with FRP in a strict setting.
I'd love to hear how your experiment goes.
- Conal
2008/12/26 Peter Verswyvelen
I'm building a little Reactive library in C# for fun - in the same spirit
as Conal's one - with the intension to convert that to F#, which I'm learning now. Right now I implemented Future, Event and Reactive, and functionality to merge/mappend two events.
Although I'm not yet sure it fully works, using some tricks from Reactive, it was actually really easy to implement. I don't need unamb stuff since I just spawn one new thread for each merged event, and I use the WaitForMultipleObjects primitive to check which of the two event occurrences was first. The code is of course a zillion times more ugly than in Haskell, and since I'm not using lightweight threads, it might really be slow. I tried to make it as immutable as possible, so it's not really imperative :)
But what is the minimal set of functions one must implement to build a Reactive library, in the sense that all others can be implemented using these?
Merry Xmas!

Thanks for the links to the LULA thesis. In the past I already briefly
skimmed over it, since it is a large document. I hope to find the time to
dig deeper in it, but I prefer to reinvent the wheel when I'm on holiday,
since it's more fun ;)
When I wrote "I don't need the unamb stuff" I actually meant "I think I
don't need unamb the way it is currently implemented since using dotnet I
can wait for either "MVar" to occur without needing to fork/kill two
threads, which gives very strange problems as you described
herehttp://conal.net/blog/posts/smarter-termination-for-thread-racing.
Note that it was mentioned by several senior GHC engineers that it is
possible to use STM to do something similar in
Haskellhttp://www.nabble.com/Re:--Haskell--Wait-for-*either*-MVar-to-be-set-td20707...
,
but still not with timeouts.
Anyway, to answer your question, with my little C# experiment I tried to
stay very close to your Reactive design, at least the parts of it that I
understand :) The goal of the experiment is mainly to get a deeper
understanding of all this without my limited Haskell skills blurring my
view, and possible GHC black-hole-bugs obstructing my journey :)
So in C# I have a Future that holds an (absolute) time/value pair (TVal)
that is either already computed (part of the "past") or might be computed in
the future. The future exposes a WaitHandle that allows waiting until the
TVal is known (with a possible timeout). Internally I use a Thunk class to
encapsulate a "Past" or "Pending" TVal; the former has no overhead and
provides a WaitHandle that is always set, the latter is a heavyweight object
that sets the WaitHandle when the TVal is written (an imperative "sink"),
waking up all threads that are waiting for this Future.
I kept the relation between Event and Reactive the same. In C#, this becomes
public class Event<T> : Future
Hi Peter,
I don't need unamb stuff since I just spawn one new thread for each merged
event, and I use the WaitForMultipleObjects primitive to check which of the two event occurrences was first.
By "was first", do you mean the occurrence itself or when it was detected? The latter is easier to implement but disagrees with the semantics (see http://conal.net/blog/posts/future-values-via-multi-threading/), which is what eventually led me to unamb.
I don't know what it takes to create and use a FRP library with pure semantics in a strict language (like C# and F#).
Since you're using WaitForMultipleObjects and working in strict languages, you might find Mike Sperber's thesis helpful: http://w210.ub.uni-tuebingen.de/dbt/volltexte/2001/266/pdf/lula-thesis.pdf. He doesn't get the simple pure semantics of classic FRP or Reactive, but he does explore some of the complex issues of dealing with FRP in a strict setting.
I'd love to hear how your experiment goes.
- Conal
2008/12/26 Peter Verswyvelen
I'm building a little Reactive library in C# for fun - in the same spirit
as Conal's one - with the intension to convert that to F#, which I'm learning now. Right now I implemented Future, Event and Reactive, and functionality to merge/mappend two events.
Although I'm not yet sure it fully works, using some tricks from Reactive, it was actually really easy to implement. I don't need unamb stuff since I just spawn one new thread for each merged event, and I use the WaitForMultipleObjects primitive to check which of the two event occurrences was first. The code is of course a zillion times more ugly than in Haskell, and since I'm not using lightweight threads, it might really be slow. I tried to make it as immutable as possible, so it's not really imperative :)
But what is the minimal set of functions one must implement to build a Reactive library, in the sense that all others can be implemented using these?
Merry Xmas!
participants (3)
-
Conal Elliott
-
Jake McArthur
-
Peter Verswyvelen