OS Jam at Google London: C# 4 and the DLR

Last night I presented for the first time at the Google Open Source Jam at our offices in London. The room was packed, but only a very few attendees were C# developers. I know that C# isn’t the most popular language on the Open Source scene, but I was still surprised there weren’t more people using C# for their jobs and hacking on Ruby/Python/etc at night.

All the talks at OSJam are just 5 minutes long, with 2 minutes for questions. I’m really not used to this format, and felt extremely rushed… however, it was still a lot of fun. I used a somewhat different approach to my slides than the normal “bullet points in PowerPoint” – and as it was only short, I thought I might as well effectively repeat the presentation here in digital form. (Apologies if the images are an inconvenient size for you. I tried a few different ones, and this seemed about right. Comments welcome, as I may do a similar thing in the future.)

First slide

Introductory slide. Colleagues forced me to include the askjonskeet.com link.

Second slide

.NET isn’t Open Source. You can debug through a lot of the source code for the framework if you agree to a “reference licence”, but it’s not quite the same thing.

Third slide

.NET isn’t Open Source, but the DLR is. And IronRuby. And IronPython. Yay!

And of course Mono is Open Source: the DLR and Mono play nicely together, and the Mono team is hoping to implement the new C# 4.0 features for the 2.8 release in roughly the same timeframe as Microsoft.

Fourth slide

This is what .NET 4.0 will look like. The DLR will be included in it, despite being open source. IronRuby and IronPython aren’t included, but depend heavily on the DLR. (Currently available versions allow you to use a “standalone” DLR or the one in .NET 4.0b1.)

C# doesn’t really depend on the DLR except for its handling of dynamic. C# is a statically typed language, but C# 4.0 has a new static type called dynamic which you can do just about anything with. (This got a laugh, despite being a simple and mostly accurate summary of the dynamic typing support in C# 4.0.)

Fifth slide

The fundamental point of the DLR is to handle call sites – decide what to do dynamically with little bits of code. Oh, and do it quickly. That’s what the caches are for. They’re really clever – particularly the L0 cache which compiles rules (about the context in which a particular decision is valid) into IL via dynamic methods. Awesome stuff.

I’m sure the DLR does many other snazzy things, but this feels like it’s the core part of it.

Sixth slide

At execution time, the relevant binder is used to work out what a call site should actually do. Unless, that is, the call has a target which implements the shadowy IDynamicMetaObjectProvider interface (winner of “biggest mouthful of a type name” prize, 2009) – in which case, the object is asked to handle the call. Who knows what it will do?

Seventh slide

Beautifully syntax-highlighted C# 4.0 source code showing the dynamic type in action. The method calls on lines 2 and 3 are both dynamic, even though in the latter case it’s just using a static method. Which overload will it pick? It all depends on the type of the actual value at execution time.

If I’d had more time, I’d have demonstrated how the C# compiler preserves the static type information it knows at compile time for the execution time binder to use. This is very cool, but would take far too long to demonstrate in this talk – especially to a bunch of non-C# developers.

Eighth slide There were a couple of questions, but I can’t remember them offhand. Someone asked me afterwards about how all this worked on non-.NET implementations (i.e. Mono, basically). I gather the DLR itself works, but I don’t know whether C# code compiled in the MS compiler will work at the moment – it embeds references to binder types in Microsoft.CSharp.dll, and I don’t know what the story is about that being supported on Mono.

This is definitely the format I want to use for future presentations. It’s fun to write, fun to present, and I’m sure the “non-professionalism” of it makes it a lot more interesting to watch. Although it’s slower to create text-like slides (such as the first and the last one) this way, the fact that I don’t need to find clip-art or draw boxes with painful user interfaces is a definite win – especially as I’m going to try to be much more image-biased from now on. (I don’t want people reading slides while I’m talking – they should be listening, otherwise it’s just pointless.)

Dynamic type inference and surprising possibilities

There have been mutterings about the fact that I haven’t been blogging much recently. I’ve been getting down to serious work on the second edition of C# in Depth, and it’s taking a lot of my time. However, I thought I’d share a ghastly little example I’ve just come up with.

I’ve been having an email discussion with Sam Ng, Chris Burrows and Eric Lippert about how dynamic typing works. Sam mentioned that even for dynamically bound calls, type inference can fail at compile time. This can only happen for type parameters where none of the dynamic values contribute to the type inference. For example, this fails to compile:

static void Execute<T>(T item, int value) where T : struct {}

dynamic guid = Guid.NewGuid();
Execute("test", guid);

Whatever the value of guid is at execution time, this can’t possibly manage to infer a valid type argument for T. The only type which can be inferred is string, and that’s not a value type. Fair enough… but what about this one?

static void Execute<T>(T first, T second, T third) where T : struct {}

dynamic guid = Guid.NewGuid();
Execute(10, 0, guid);
Execute(10, false, guid);
Execute("hello", "hello", guid);

I expected the first call to compile (but fail at execution time) and the second and third calls to fail at compile time. After all, T couldn’t be both an int and a bool could it? And then I remembered implicit typing… what if the vaue of guid isn’t actually a Guid, but some struct which has an implicit conversion from int, bool and string? In other words, what if the full code actually looked like this:

using System;

public struct Foo
{
    public static implicit operator Foo(int x)
    {
        return new Foo();
    }

    public static implicit operator Foo(bool x)
    {
        return new Foo();
    }

    public static implicit operator Foo(string x)
    {
        return new Foo();
    }
}

class Test
{
    static void Execute<T>(T first, T second, T third) where T : struct {}

    static void Main()
    {
        dynamic foo = new Foo();
        Execute(10, 0, foo);
        Execute(10, false, foo);
        Execute("hello", "hello", foo);
    }
}

Then T=Foo is a perfectly valid inference. So yes, it all compiles – and the C# binders even get it all right at execution time. So much for any intuition I might have about dynamic typing and inference…

No doubt I’ll have similar posts about new C# 4 features occasionally… but they’re more likely to be explanations of misunderstandings than deep insights into a correct view of the language. Those end up in the book instead :)