Reactive programming in javascript and C#
I stumbled on a cool javascript project: Flapjax. The library part is quite interesting (ie. ignore the language/compiler part). It provides a functional abstraction over push-based event processing, which is useful for asynchronous programming and interactive applications.
The two concepts it offers are: time varying values, also called "behaviors", and discrete sequences of values, also called "events".
Behaviors (noted B in Flapjax) always have a value, but may change at any time, while Events (noted E) are a discreet sequence of values.
The library offers a number of functions for creating event streams from common javascript objects (such as DOM elements), transforming/filtering streams, as well as converting between E and B types (see "snapshotE" and "startsWith" functions) and merging/joining streams (see "mergeE" function).
For example, a useful utility function is "calmE", which returns a throttled event stream. See the Flapjax API reference for more.
Asynchronous methods (such as calling the server) fit naturally in this design and are also captured as transforms, which take one event stream of requests as an input and outputs an event stream of response (which you can feed into the next step of local processing).
This lets you chain operations, LINQ-style, into an event processing pipeline where each stages pushes to the next.
This brings us to the .Net world. There are already some projects attempting to improve .Net and LINQ for asynchronous programming (CCR, Polyphonic C#/Cω Bindable LINQ, PFx/TPL with ContinueWith on Tasks and Futures<>), but most excitingly, this will officially be included in .Net 4.0 under the "Rx" framework. It brings the new IObservable<> type, a sibling to the existing IEnumerable<> type, which powers much of LINQ, with much of the same composability benefits.
Erik Meijer's initial presentation on the Rx framework explains the deep similarity between those types and the symmetry between the push and pull flows.
An early version of the System.Reactive assembly is available in the Silverlight 3 release. Jafar Husain has been toying with those bits and blogging about their experience, starting with an excellent introduction, Introducing Rx, LINQ-to-events.
One interesting problem is how to clean up the resources in the chain after the data is done flowing, or once a listener is no longer interested. With IEnumerable, the solution is having disposable IEnumerators, which constructs like "foreach" take care of (see section 8.8.4 of the C# spec).
Rx solves this elegantly as well by returning an IDisposable object representing a subscription of a specific listener to an IObservable. Disposing this subscription handle unsubscribes the listener.
This is a definite improvement compared to native .Net events, which are notoriously tricky to clean, especially if you use anonymous methods as listeners.
Wes Dyer and Kim Hamilton give a good presentation of the IObservable API as it stabilized to be included in the .Net 4.0 BCL, including the problem of dangling events and interesting other framework design considerations (naming, expectations, etc.).
The IObservervable API looks something like the following.
interface IObservable
IDiposable Attach(IObserver
}
interface IObserver
void Yield(T event);
void Break(); // this was the last event from this source.
void Throw(Exception ex); // source blew up. no more events.
}
PS: As a brain-teaser, I can't help but mention that Flapjax uses trampoline-style programming to handle events, since Javascript is single-threaded. If you are not familiar with that mind-twisting trick, it relies on generators (the javascript equivalent of IEnumerable iterators) to slice functions into smaller units which are invoked/pulled by a controller. Here's my previous write-up on trampoline-style multi-threading in javascript.
PPS: Neat innovations like the Reactive Framework keep reminding me of what a well-designed language C# is, as its support significant programming abstractions to be implemented naturally and efficiently as libraries.
Now the problem is converging the different asynchronous programming models developed on .Net (events, Parallel FX, Rx framework).
Update: The initial version of Rx was released for download.
Updated Rx has hopped from .Net back to Javascript, in the form of RxJS.