At this year's Professional Developers Conference (PDC 2008), Microsoft® was quite forthcoming with specifics about the future for developers on the Microsoft .NET® platform. In this article, we will take a quick look at some of the upcoming features in the .NET 4.0 Framework, the new Microsoft F#® language, and discuss the long-term vision Microsoft has for the .NET Platform in the years to come.
One of the most prominent messages coming from Microsoft right now is geared towards Microsoft Visual Basic® .NET developers. VB.NET and Microsoft Visual C#® are both built on top of the Common Language Runtime (CLR), which means they both compile down into the same Common Intermediate Language (CIL). Since they both compile down to the same code, there should be no intrinsic benefit of one language over another. However, both languages are maintained by separate teams at Microsoft, and over the years this separation has led to a variety of language-specific features in both C# and VB.NET as the teams focus on different areas with their respective products. Many VB.NET developers feel that the most exciting new features appear in C# first and are only later introduced into VB.NET. Naturally, this has generated a bit of animosity in the VB.NET community.
Co-evolution is a promise from Microsoft that recognises VB.NET and C# as equally important languages, and guarantees that as new language features evolve, those features will be incorporated into both languages simultaneously. No longer will you need to second guess your decision to go with a particular language for want of a particular feature, and the debate between which language is "better" will be reduced back down to syntactic preference. And while C# developers will probably have a lingering superiority complex with which VB.NET developers will have to contend, all VB.NET developers need to do is remind the C# devs that it's all the same under the covers.
Introducing the Dynamic Language Runtime
Microsoft is acutely aware that the .NET Framework is not the only choice for building applications. All you have to do is take a quick glance around the development sphere and you'll find a number of language options, and that number is only expected to rise as domain-specific languages emerge. People are spending time and energy writing useful components in these languages, so the question is, how can you use a component written in another language without having to rewrite it in .NET?
At a high level, you can think of the Dynamic Language Runtime as having three layers (see figure 1 below):
- .NET Language Integration
- DLR Core Components
- Language Binders
Figure 1. Dynamic Language Runtime (Slide courtesy of Anders Hejlsberg and Jim Hugunin's presentation at PDC 2008.)
The first layer, .NET Language Integration, simply represents the need for .NET languages to have a notion of what the DLR is and how to use it. For the most part, you won't even notice this aspect of the DLR because most of the .NET languages had a natural integration point. IronRuby and IronPython are both dynamically typed languages, so the DLR fit right in. VB.NET has always supported the notion of late binding on the Object type, so the DLR incorporated nicely into late binding resolution. C#, however, has no notion of late binding and needed an additional static type for dynamic language support. It's called the dynamic type, and we'll talk about it in more detail a bit later.
The second layer is the Dynamic Language Runtime itself, which consists of three core components: Expression Trees, Dynamic Dispatch, and Call Site Caching. An Expression Tree is a representation of code in the form of a tree, which helps abstract languages into a consistent format on which the DLR can operate. Once dynamic code is in a tree representation, the DLR can look at the tree and generate CLR code from that tree for actual execution. Parsing dynamic code into an expression tree and then building the CLR is an expensive operation, so the DLR employs a performance technique known as Call Site Caching to avoid having to "recompile" the dynamic code each time it's called. Dynamic Dispatch ensures that appropriate Language Binders are used for dynamic invocations.
Language Binders, which make up the third layer, are language-specific implementations of certain operations the Dynamic Language Runtime needs to understand about each language that wishes to participate in the DLR.