Living in the Tech Avalanche Generation

A practitioner’s introspective on technology

Archive for the 'F#' Category

Curried Event Handlers or - Lazy Event Handling in Functional C#

There has been a lot of buzz lately about the ‘other’ styles of programming that exist outside of our warm and cosy statically typed imperative world. Dynamic and Functional programming languages are starting to generate some deep interest in the community and anyone who reads this blog from time to time would know that I too have been dragged in by the gravity of IronRuby.

F#, whilst interesting to me, alas must take a back seat to IronRuby as it’s going to have to be one language at a time for this little polyglot, however I keep coming across interesting information that promotes a Functional approach in C# and VB.NET. The approach leverages some of the newer (3.5) language features syntactically but really the core of what’s possible lies in the what became available in C# 2.0. There is of course always a ubiquitous example so lets stick with that - a function that takes an integer as an argument and returns a function that also takes an integer as an argument and returns an integer that adds the two together. Consider this code:

[Test()]
public void CurryInTwoDotZeroFramework()
{
    FuncInTwoZeroStyle two_zero_func =
        new FuncInTwoZeroStyle(delegate(int x)
            {
                return delegate(int y)
                {
                    return  x + y;
                };
            });

    var first_func_has_10 = two_zero_func(10);
    var second_func_has_another_10_makes_20 =
        first_func_has_10(10);

    Assert.AreEqual(20,
        second_func_has_another_10_makes_20);
}

functional_delegates_watch 

What’s happening here is that we get a kind of closure behaviour where 10 gets stored away with the function. From the compilers point of view we know that delegates at runtime have a class generated with a target and a method and in our example we have 10 as the object instance being the target and the returned function is the “Method” that gets wrapped up in our runtime generated class. For a good discussion on how delegates work under the hood it’s worth reading this post.

Currying – a style of cooking or programming practice?

Something that Functional devotees often talk about is the ability to write functions that return functions, often referred to as “currying”. Interestingly the Wikipedia definition includes the following:

The practical motivation for currying is that very often the functions obtained by supplying some but not all of the arguments to a curried function (often called partial application) are useful; for example, many languages have a function or operator similar to plus_one. Currying makes it easy to define these functions.

Our .NET 2.0 example above can be redefined in 3.5 with some syntactic sugar like this:

public void basic_add_Curry()
{
    Func<int, Func<int, int>> curry_add_ten =
        x => y => x + y;

    var add_to_10 = curry_add_ten(10);

    var should_be_20 = add_to_10(10);
    var should_be_30 = add_to_10(20);
    var should_be_40 = add_to_10(30);

    Assert.AreEqual(20, should_be_20);
    Assert.AreEqual(30, should_be_30);
    Assert.AreEqual(40, should_be_40);
}

 

You mentioned Events?

I don’t want to go over ground already largely covered elsewhere so let me focus in what I thought was a slight deviation that offered up an interesting possibility. What about event subscriptions? Can we ‘curry’ event handlers? The answer is yes of course we can. Let me demonstrate.

internal class MyObjectWithAnEvent
{
    internal event EventHandler subscribe_with_action_event;

    internal void on_subscribe_with_action_event()
    {
        if(subscribe_with_action_event != null )
            this.subscribe_with_action_event
                ("’an event subscribed to by Action<>’",
                    new EventArgs());
    }
}

and we can subscribe to the event in this class like this:

public void event_handling_curry()
{
    //simple Action delegate
    Action<int, int> takes_two_ints =
        (x, y) => Console.WriteLine(x + y);

    takes_two_ints.Invoke(2,3);

    //Action matching signiture of EventHandler delegates
    Action<object, EventArgs> a_standard_event_delegate =
        (x, y) => Console.WriteLine(String.Format("{0}:{1}", x, y));

    //new up an object that has an event to subscribe to
    MyObjectWithAnEvent obj_to_subscribe_on =
        new MyObjectWithAnEvent();

    //subscribe to the event that implements 
    //an EventHandler delegate
    obj_to_subscribe_on.subscribe_with_action_event +=
        new EventHandler(a_standard_event_delegate);

    //call a method to raise the event
    obj_to_subscribe_on.on_subscribe_with_action_event();

    //declares a function that returns an event handler
    Func<int, Action<object, EventArgs>>
        func_that_returns_event_delegate =
        x => (y, z) => Console.WriteLine(
            string.Format("The values passed to the function was {0} " +
            "and the sender was {1}", x, y));

    //store the value of 100 with the returned event handler
    var action_with_int = func_that_returns_event_delegate(100);

    //subscribe to an event with the delegate 
    //returned by the function
    obj_to_subscribe_on.subscribe_with_action_event +=
        new EventHandler(action_with_int);

    //raise the event
    obj_to_subscribe_on.on_subscribe_with_action_event();
}

What is evident here is that we have returned a delegate that also has access to the contextual data that we had available at runtime when the delegate was computed. This delegate along with the the contextual data (x being equal to 100) might subsequently be used in a further computation at such time as any event is raised in which that delegate in question has been applied as a handler in any such events invocation list. I call this ‘contextual delayed subscription’. Perhaps I want to get a reference to a handler for an event that has not yet occurred and upon certain conditions or actions I will subscribe to that event at a later time or perhaps Just in Time. For example you might choose to store away the delegates and their contextual state until a user of your application indicates that they are interested having an event subscribed where actions occurring in the past are also of interest.

Share/Save/Bookmark

1 comment

learning Ruby, IronRuby, the DLR, F# and DSL’s - so much to consider.

ruby I just cant seem to shake Ruby off. Often something comes up in my day to day job that pushes me get serious about Ruby and for as long I have the idea of the Polyglot programmer in the back of my mind, I feel compelled to find out more, even if it’s in microscopic increments. A while back I installed Ruby on my development laptop and played with the interactive console for a while and then predictably got distracted and didn’t follow up for months, until today when I  downloaded NetBeans (Ruby version only) and made a decision, that to understand Domain Languages better I wanted to learn more about a language that would help in that understanding. Ruby is well thought of with respect to being a useful language to ms rubydevelop internal DSL’s and given the other sentiment in this post, I thought it was as good a choice as any. I have been a C# developer since beta of the 1.0 Framework and now that IronRuby and DLR are close at hand, I feel compelled to let my interest in DSL’s, the DLR and learning a dynamic language begin to engulf me to the point that I have been stung into action. So with this in mind I am setting down the path to learn Ruby and hope that this provides a great springboard into taking up IronRuby. Of course the benefit of going deep into another development language and platform I believe will lead to a far richer appreciation of the platform I am currently so deeply invested in.

Last Minute Update:

After re-listening to the HanselMinutes podcast with Robert Pickering on F#, it would appear that F# is a potentially useful language for creating internal DSL’s. I have been thrown a little as I must confess this threw things into debate for a short moment. The argument that kept me down the Ruby path was the relationship that IronRuby has with the DLR and the upside that brings to the learning experience. FsharpYellow Last minute problem solved. Wait hold the press. VbX or Visual Basic 10 is on its way and it too will be a dynamic language. Dilemma. Given that I am almost  equally conversant in VB as C# (I prefer C# by choice), perhaps I should concentrate on F# and let my strong understanding of VB languages to carry me through the transition to VB10 which gives me the DLR leverage? Again I decide to take the Ruby path also because its not a Microsoft Language per se and I think the exposure to Ruby in general will do me good from a platform perspective. I would also like to use Ruby in exploring RESTful Web Services. So I have downloaded NetBeans and installed Ruby 1.8.6 and here I go.

Share/Save/Bookmark

1 comment

Creative Commons Attribution-ShareAlike 2.5 Australia
Creative Commons Attribution-ShareAlike 2.5 Australia