Phillip Trelford's Array

POKE 36879,255

Mini Rx: Observable Extensions

The Reactive Extensions (Rx) provide LINQ style querying capabilities for events in C#, VB.Net and JavaScript. Rx implements extension methods over IObservable<T>, just as LINQ to Objects provides a set of extension methods over IEnumerable<T>,

ReactiveExtensions4dotNet

There has been a fair amount of Microsoft publicity on the Rx library in blogs, videos and talks. Demand for Rx skills in IT jobs has grown over the last 12 months. 

Reactive Extensions Demand Trend

That said, the current implementation of the Rx library has at least a couple of issues:

Given that LINQ is based partly on higher-order functions from functional programming perhaps it’s not surprising F# supported querying over events back in 2006. It’s also relatively trivial to expose this functionality to C# by defining compatible extension methods using the ExtensionAttribute e.g.

[<Extension>]
type ObservableExtensions private () =
   [<Extension>]
   static member Select<'T,'U>(source:IObservable<'T>,selector:Func<'T,'U>) =
       source |> Observable.map selector.Invoke
   [<Extension>]
   static member Where<'T>(source:IObservable<'T>,predicate:Func<'T,bool>) =
       source |> Observable.filter predicate.Invoke
   [<Extension>]
   static member Subscribe<'T>(source:IObservable<'T>, action:Action<'T>) =
       source |> Observable.subscribe action.Invoke

This is already enough to provide basic LINQ syntax in C# for types implementing IObservable<T>:

var leftPressedMove =
    from e in mouseMove
    where e.LeftButton == MouseButtonState.Pressed
    select e;

F# custom events implement IObservable<’T> by default and F# provides modules with higher-order functions for both .Net Events and the IObservable<’T> interface.

For C# a mechanism is needed to convert .Net events to an object that implements IObservable<T>. This can be achieved fairly concisely in F# using object expressions:

let FromEvent<'TEventArgs, 'TDelegate when 'TEventArgs:> EventArgs>
    (conversion:Func<Action<'TEventArgs>,'TDelegate>,
        addHandler:Action<'TDelegate>,
            removeHandler:Action<'TDelegate>)  =
    { new IObservable<'TEventArgs> with
        member this.Subscribe(observer:IObserver<_>) =
            let handler = Action<_>(observer.OnNext) |> conversion.Invoke
            addHandler.Invoke handler
            let remove () = removeHandler.Invoke handler
            { new IDisposable with member this.Dispose() = remove () }
    }

Although converting from the event in C# feels a little convoluted:

var mouseMove =
    Observable.FromEvent<MouseEventArgs, MouseEventHandler>(
        f => new MouseEventHandler((sender, args) => f(args)),
        handler => MouseMove += handler,
        handler => MouseMove -= handler);

Again for C# a mechanism is required for directly creating objects that can be both a source of events and be used to observe events. Rx follows the Observer pattern and provides a type called Subject that implements both IObserver<T> and IObservable<T>.

Earlier in the year I put up 2 simple types on F# Snippets, that are functionally equivalent to Rx’s Subject<T> and ReplaySubject<T>:

The ReplaySubject implementation uses F# Agents to simplify concurrency..

The types can be used easily from C#:

var s = new Subject<int>();
s.Subscribe(Console.WriteLine);
s.OnNext(1);

For Silverlight and WPF we need a mechanism for invoking methods on the UI thread, which I implemented in F# back in 2010: Implementing IObservable and extending Observable 

mouseMove
    .Select(e => e.GetPosition(canvas))
    .Delay(closure * 100)
    .OnDispatcher()
    .Subscribe(pos =>
    {
        Canvas.SetLeft(label, pos.X + closure * 10);
        Canvas.SetTop(label, pos.Y);
    });

Putting it altogether, the inevitable "time flies like an arrow" Silverlight demo:


In case you’d like to have a play yourself, I’ve put up a preview release on CodePlex:

http://minirx.codeplex.com/

Turtle Graphics

Over time I’ve been trying to engage my young children with computer programming, so far we’ve looked at Squeak, Small Basic and more recently F#.

They really enjoyed playing with the Turtle in Small Basic, an idea that comes from Logo, a programming language I myself played with as a child.

For i = 1 to 4
  Turtle.Move(100)
  Turtle.TurnRight()
EndFor

Small Basic is a variant of Basic with just 14 keywords. It also ships with a library of static methods for fun stuff like graphics and sound, removing the need to understand the vagaries of threading before getting started.

The SmallBasicLibrary.dll can be also be referenced from C# and F#. However, rather than using value types for passing parameters, it defines it’s own union type called Primitive and associated implicit conversions, a little like the Variant type used in Visual Basic.

I’ve been trying a few different ways of bringing first class Turtle graphics to F#. A few months back I created a simple internal DSL in F# that looks quite a lot like Logo, and can be run in the browser:

repeat 10 [rt 36; repeat 5 [fd 54; rt 72]]
|> Turtle.Run

Just hit the TryFSharp.org button on this Turtle F# Snippet, or download the Silverlight code.

TurtleInternalDSL

More recently based on some of the ideas in the Small Basic Library, I’ve created a small library for C# and F# called Small Sharp, which is hosted on CodePlex.

using Library;

class Program
{
    static void Main(string[] args)
    {
        GraphicsWindow.Show();      
        Turtle.PenName("Red");
        (1000).Times(i =>
        {
            Turtle.Forward(6);
            Turtle.Right(i * 7);
        });
    }
}

Small Sharp provides a fun environment to learn about programming, while giving you the full power of either the C# or F# programming languages. It also includes some LINQ and Ruby like extension methods, for example the sample above runs 1000 times.

TurtleCSharp

Instructions for getting started with C# and F#

DDD Belfast 2011

This weekend I flew into Belfast for their Developer Developer Developer (DDD)  conference. The DDD conferences are run by the developer community for the developer community, where sessions are voted on prior to the conference. I highly recommend these free events, there always seems to be a great range of interesting talks, not to mention plenty of lively discussion between sessions. The next event is DDD North next weekend, Saturday 8th October, in Sunderland.

Interestingly there were enough F# sessions at DDD Belfast to have a dedicated track (3), which is where I spent most of the day.

My first talk of the morning was F# Eye 4 the C# Guy (a title I ahem, recycled, from an excellent talk by Leon Bambrick given 3 years ago):

Next up was Tomas Petricek on Asynchronous Programming in F# and C#. If you’re in London, Tomas is repeating this talk at Skills Matter this Wednesday (5th October), register free here: http://www.meetup.com/fsharpLondon/

Shipping in VS11, C# 5’s Async (await) support will be very similar in implementation to C# 2’s Iterators (yield). They are both basically implementations of coroutines.

F#’s Async Workflows are available now in VS2010.

Before lunch I was up again to talk about Behavioural Driven Development (BDD) with F#:

After lunch Adam Granicz presented Developing F# Applications with WebSharper on track 3. I popped over to see Richard Dalton’s great information packed session Aha! Unit Testing.

Slides and samples: http://www.devjoy.com/2011/10/aha-unit-tests-dddbelfast/

Richard gave some really interesting observations, for example unit tests are “An Extra Client” (slide 5), and therefore it is OK to add artefacts in your code to support them. The talk presented a number of Aha! moments:

Unit Testing - Excutes Unit Testing - Real Reason

 

There were also some good tips on Mocks and Stubs (Stubs are Stooges, Mocks are Spies), including some code examples using TypeMock and references to Microsoft Research’s Moles project and Martin Fowler’s Mocks Aren’t Stubs article.

Track 3 ended with a lively Panel Discussion, which covered a variety of subjects from BDD, Concurrent programming with Agents, Parsers, Units of Measure through to games development.

Thanks again to all the attendees, sponsors, speakers and particularly Jackie Pollock for organizing the event.