DDD9, teaching Jon Skeet C#, and fun with exceptions

DDD9

Last weekend I presented my Functional Alchemy talk at DDD9, to a room full (and I mean full) of smart, enthusiastic developers who were spending their Saturday seeking new ways to become better at their jobs. I had a great time, and the feedback I’ve had has been incredibly positive, so I think I made it worth their while.

The day got off to an auspicious start in Liam Westley’s excellent talk on the Async CTP, which covered the new pair of keywords proposed for C# 5: async and await. These two little words abstract away a whole world of complexity around non-blocking asynchronous processing – NOT parallel processing, mind – and save you having to clutter up your code with acres of boilerplate around continuations, exception handling, scope, control flow and so forth.

The evening before Liam told me he was hoping to get a mini-panel to discuss the proposal for 10 minutes at the end of his talk, and because I’m a pathological attention whore I volunteered my services. And so it was that I found myself at the front of the room with Jon Skeet, of Stack Overflow and C# mastery fame, and Mike Hadlow, who was up next with his talk on Monads and who already has language-level support for Async because he knows F#. Jon said he thought the feature was great. I suffered an error between brain and mouth and started off sounding like I thought they shouldn’t be keywords, when what I meant to say was that I didn’t like the actual keywords that were chosen (see below). Mike thought this represented the first time C# programmers had been treated like idiots by the language team, which was plainly the opinion of a madman. C# programmers have been treated like idiots from Day 1, when it was decided we couldn’t be trusted to clean up after ourselves and needed a garbage collector*.

(The “await” keyword

What I don’t like is that the await keyword, to me, suggests that your code is going to block on the thread until the call you “await” returns. Which is, obviously, no different from just calling it synchronously. However, I have not been able to come up with a better word of seven letters or fewer which does convey the full meaning of “suspend execution of this code block and free this thread up to handle other stuff until such time as the asynchronous task that I am invoking completes and provides a notification to that effect.” Maybe “await” isn’t that bad.)

Teaching Jon Skeet C#

Obviously bobbins. I don’t think Jon learned anything new about C#, although maybe something made him go “oh yeah, that’s a good idea.” But I tell you what, when you’re giving a talk on what you hope are some fairly original and advanced uses of the functional-style features of C#, and the man who wrote the book on advanced C# is in the audience, well, that throws you for a start. When said man sticks his hand up about 10 minutes in to ask a question, it’s going to go one of two ways. Thankfully, it went the good way, and Jon’s occasional contributions were more constructive or additive than challenging. And he was right about the Dictionary.

Fun with exceptions

One of Jon’s contributions was around a popular part of the talk, where I demonstrate a method for using generics and lambda expressions to create a pseudo-try/catch block which will allow multiple types of exceptions to be specified in a single line.

Like this:

TryCatch.Try(() =>
                 {
                     using (var stream = File.OpenRead(FileTextBox.Text))
                     {
                         Trace.WriteLine(stream.Length);
                     }
                 })
.Catch<FileNotFoundException,
        DirectoryNotFoundException,
        UnauthorizedAccessException>
    (ex =>
    {
        MessageBox.Show(ex.Message, "Fail");
    });

This code uses a static method to create a TryCatch object which hangs onto an Action (in this instance, the File.OpenRead section), then exposes multiple generic overloads (i.e. a method which is overloaded by having different numbers of generic parameters) of a Catch method which executes the Action, catches the exception types specified in the generic parameters, and executes an Action<Exception>. The idea is that it saves copy-and-paste on the code in the catch block, where that code is all the same.

Jon asked why the “using” block should not also be abstracted away into the TryCatch class; I hadn’t thought of that and asked if he’d like to give it a try with me after the talk, which he did.

Functional programming is really, really easy.

The code in the Try method is incredibly straightforward:

class TryCatch
{
    private readonly Action _action;

    private TryCatch(Action action)
    {
        _action = action;
    }

    public static TryCatch Try(Action action)
    {
        return new TryCatch(action);
    }

That’s it. It just instantiates the type with the Action. The clever bit is all in the Catch methods, which I won’t go into in this post; go download the code from bit.ly/functionalalchemy and read it, it’s quite straightforward.

So we took a look at how we could create a TryUsing method, and it turned out to be a great example of functional composition. All we needed to do was add an extra parameter – the object to be “used” – and then create a new anonymous method which wrapped the Action execution in a using block. Look, I’ll show you:

public static TryCatch TryUsing<T>(T resource, Action<T> action)
    where T : IDisposable
{
    return new TryCatch(() =>
    {
        using (resource)
        {
            action(resource);
        }
    });
}

See? Easy. We’re still not executing the action, we’re just creating a new method around it.

Of course, when we hooked this up to the demo code, everything broke spectacularly, and the exception stopped getting caught, and it took us a couple of minutes to figure out why. See if you can spot our mistake before reading on.

Yes indeed: we were creating our stream outside of the call to TryCatch, so we could pass the Stream as a parameter to our new TryUsing method. A tiny bump, rather than a pothole, and an excellent example of some other things from the demo: higher order functions and deferred execution. Rather than passing the object to be used, we needed to pass the way to create the object, so that the creation could also be wrapped in the TryCatch magic.

public static TryCatch TryUsing<T>(Func<T> resourceCreator, Action<T> action)
    where T : IDisposable
{
    return new TryCatch(() =>
               {
                   using (var resource = resourceCreator())
                   {
                       action(resource);
                   }
               });
}

And that’s working. Here’s the call from the consumer:

private void TryWithUsing()
{
    TryCatch.TryUsing(() => File.OpenRead(FileTextBox.Text),
                      stream =>
                      {
                          Trace.WriteLine(stream.Length);
                      })
        .Catch<FileNotFoundException,
            DirectoryNotFoundException,
            UnauthorizedAccessException>
        (ex =>
             {
                 MessageBox.Show(ex.Message, "Fail");
             });
}

The awesome thing here is that there were no changes required anywhere else in the TryCatch class; we just had to mutate the Action that was being passed to the constructor.

BTW, a few people pointed out that because these are all single line methods, they could be expressed using lambda expression syntax, and this is true. The reason I don’t do this in the demo is because I want to maintain the similarity to a regular try/catch block, but once you’re happy with this style of programming, you can happily format the above method thusly:

private void TryWithUsing()
{
    TryCatch.TryUsing(() => File.OpenRead(FileTextBox.Text),
                      stream => Trace.WriteLine(stream.Length))
        .Catch<FileNotFoundException,
            DirectoryNotFoundException,
            UnauthorizedAccessException>
        (ex => MessageBox.Show(ex.Message, "Fail"));
}

I’ve updated the code at Bitbucket with these changes, (and also uploaded it to Github for those more CLI-inclined (inCLIned?)), so go download it and have a play. It’s under MIT License, so feel free to use any of it in your own applications.

In summary, then:

I had a brilliant day at DDD9. My talk went well, I enjoyed the other talks I saw, I chatted and coded and generally hit it off well with Jon (and we’re hoping to do a two-handed talk in the second half of the year), and overall I can’t wait for the next DDD event. Hopefully that’ll be Scotland in May.

Footnote

*Irony.

Comments

  1. 7 letters: suspend – the first word in your description of what await does, and possibly a suitable replacement for the keyword?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 4,019 other followers

%d bloggers like this: