Dynamic Languages in .NET 4.0

What is Dynamic Typing?

Programming Languages can be classified under two categories based on the Type checking: 1. Static typed languages and 2. Dynamic typed languages. In Static typed languages, the type checking is performed at the compile time. Examples include C, C++, C#, Java, ForTran, Pascal, Haskell etc. In Dynamic typed languages, the type checking is performed at the run-time. Examples include Javascript, LISP, PERL, PHP, Python, Ruby, Prolog etc.

What is Dynamic Programming?

The word “Dynamic” in Dynamic Programming is not just limited to Dynamic Typing. It means talking to anything which is not statically typed to .NET class.

Wikipedia defines Dynamic Programming languages as follows:

Dynamic programming languages are a class of high-level programming languages that execute at runtime, many common behaviors that other languages might perform during compilation. These behaviors could include extension of the program, by adding new code, by extending objects and definitions, or by modifying the type system, all during program execution.

What is Meta Programming?

One of the main advantages of Dynamic Programming languages is the ability to use Read – Eval – Print loop, which allows us to enter code snippets at run time, get them executed at run time and see the results immediately. In other words, Dynamic languages allow us to do Meta Programming.

Wikipedia defines Meta-Programming as follows:

Meta-Programming is the art of writing computer programs that write or manipulate other programs as their data or that do the part of work at run time that would otherwise be done at compile time.

What is Dynamic Language Runtime?

IronPython and IronRuby were the Dynamic languages developed targeting the .NET framework. Now, the .NET embraces them with its Dynamic Language Runtime. We know that Common Language Runtime (CLR) is a common platform which unifies Statically typed languages to operate in .NET platform. Though it had some dynamic capabilities like Reflection, it was not intended to be mainly for Dynamic Programming. The Dynamic Language Runtime (DLR) is a common framework on top of CLR developed to allow the dynamic languages to interoperate in .NET. Checkout Jim Hugunin’s talk on DLR at Microsoft’s Professional Developer’s conference, 2008. DLR can be downloaded in Codeplex. It is also available in Visual Studio 2010 CTP.

What is the architecture of DLR?

Dynamic Language Runtime supports

  • Dynamic languages like IronPython and IronRuby,
  • Dynamic features introduced in static typed languages like C# and VB.
  • Upcoming Dynamic languages like Iron Scheme

Through DLR, the Dynamic languages can interact with .NET objects, Silverlight, Python, Ruby and Microsoft Office objects through Binders. With these Binders, we get a common programming experience to talk with both statically typed and dynamic typed objects.

The DLR is composed of the following three components which accomplishes all its goals:

  1. Expression trees – Allows the DLR to play with code at runtime
  2. Dynamic Dispatch – Allows the Dynamic languages to communicate with themselves and other objects in a shared way; similar to static dispatch of CLR, which allows static objects to communicate with each other
  3. Call site caching– Improves performance of Dynamic Dispatch

IronPython and IronRuby were the implementation of the Dynamic languages Python and Ruby languages running in .NET. They were Iron-ified as they are true language implementations – they do not change the original language specification. They bring with them a unique experience from Dynamic languages world. They integrate easily with .NET libraries, other .NET languages, .NET hosts and .NET tools. They can rightly be termed as Implementation running on .NET.

“Dynamic” keyword:

For example, let us say we have a method GetCar() retuning an object of type Car, which is a .NET object.

Car newCar = GetCar();
newCar.Start();

 
Because the method GetCar() returns a statically typed .NET object, we can call methods on them through Reflection.

Now, let us consider the method GetCar returns an object, which is not a .static NET type, like a COM object or a Javascript object. If an object is of .NET type but not known at compile time, we can use Reflection to invoke the method and get its object dynamically. If it is a Javascript object, we have to get a Script Object and invoke its method. Hence the way of method invocation varies with each dynamic type.

To provide a common way of interacting with these dynamic objects, C# 4.0 introduces a statically type called “dynamic” which indicates that an object is of Dynamic type. Check out Ander’s talk on the Future of C# in Microsoft’s Professional Developers Conference, 2008.

Here “newCar” is a dynamic typed object and when we call the Start method, we are doing a Dynamic method invocation. The DLR allows us to call any method on this dynamic object, because the method will be resolved at run time. It indicates that, whatever the type the dynamic object will assume at run time, the compiler has to bind the method to the dynamic object (Dynamic Dispatch).

When a dynamically invoked method returns an object which is assigned to of static .NET type, we are doing a Dynamic conversion.i.e., there is an implicit conversion from run time type to Type “Double”.  Explicit conversions are also possible. Chris Burrows explains the intricacies of Dynamic Conversions.

Dynamic Lookup allows us to write method, operator and indexer calls, property and field accesses, and even object invocations which bypass the C# static type checking and instead gets resolved at runtime.

Check out Sam Ng’s blog post 1 and post 2, which describes how programming with Excel is simplified using dynamic objects. He also explains the different ways of using a dynamic type here and here. Check out how it describes what happens at compile time and at runtime and how the Runtime binder works. It also describes what Dynamic receivers and explains Call-site Binder creation.

Dynamic programming has come to ease the way we interact with non-.NET objects, which otherwise would involve complex or lot of code. This doesn’t mean Dynamic Programming is going to replace Static Programming. Static Programming has its own advantages like Compile Time type checking, Getting errors resolved at compilation, Improved performance etc.

Dynamic variables

Consider the code,

Here the compile time type is Dynamic and the Runtime type is Int32. The dynamic keyword allows the type of object to be deferred at runtime.

Anything can be assigned to a “dynamic” object.

Dynamic operands

When one or more of the operands are dynamic, the member selection is deferred to runtime. The actual type is substituted at run time and Overload Resolution is done at runtime just like at compile time.

The following code will call the first overload method.

The following code will call the second overload method.

Notice that, Operations involving dynamic operands are considered Dynamic operations and their result type is also dynamic. Sometimes, even a Static method when it accepts a Dynamic argument is dispatched dynamically. Check out Chris Burrow’s post  and SamNg’s post to understand how Dynamic Overload Resolution works.

When we look at the Metadata, dynamic objects are just objects with an attribute signifying that they are dynamic.

Dynamic properties

Properties can be get and set dynamically. The dynamic object acts as a dynamic receiver when its value is set. The compiler indicates to the runtime, that it needs to bind the dynamic object with a property called “Name” and that a value of “1” has to be set.

Dynamic delegates

Dynamic variable can be invoked as a delegate. In this case, the run time does the work of delegating the method call.

Dynamic Indexers

Through Indexers, values can be get and set dynamically. (This does not work with CTP. It throws a Compile time error saying “Cannot apply indexing with [] to an expression of type ::dynamic”. CTP bits were older than those used in PDC Demo). The runtime binds the dynamic object with the Indexers.

Dynamic Operators

Operators can be called on Dynamic variables. (This does not work in CTP. A Compile time error message “Operator + cannot be applied to operands of type :dynamic” is shown. CTP bits were older than those used in PDC Demo). The operator “+” is a dynamic operator because one of its arguments is dynamically typed. The runtime does the Operator overload resolution on the dynamic object.

Check out SamNg’s blog post to see how Dynamic Indexers and Operators work.

How are Expression trees used in DLR?

DLR uses Expression trees to simplify the way it interprets the dynamic operations from different dynamic languages, each with different semantics.  Check out Jim Hugunin’s post on Thinking DLR as Expression trees. Every operation is considered as an expression tree. By considering to use Dynamic operations instead of Static operations, Dynamic Programming becomes simpler for the DLR, even when applied to different languages. Dynamic operations do Dynamic method invocation and Overload Resolution, thus adding the “Dynamic” capability. Using Expression Trees, the processing becomes even simpler than through usage of IL. The features of Expression tress are : they are analyzable, transformable and composable. They are transformed into Optimised Machine Code by the JIT compiler. They can be constructed easily and are easily collectible.

What is Call-site Caching?

Call-site caching help in making the Dynamic Dispatch run faster. A callsite is an object that is generic on the type of delegate. CallsiteBinder helps in doing the specific binding required for a callsite based on the arguments. It speeds up the runtime method binding by remembering the results of a previously method looked up at the call site. Callsite also helps in sharing objects across objects. They can be customized for every language. Check out Sam Ng’s blog and Chris Burrows blog to understand how the call site works. mmaly explains how DLR caching works.

Custom Dynamic Objects

Custom Dynamic objects can be created by inheriting from IDynamicObject interface. (This type is not present in CTP.  CTP bits were older than those used in PDC Demo). Check out Chris Burrow’s blog post on how to implement a Custom Dynamic object. Mark Michaelis describes how to implement a dynamic XML object.

Dynamic Objects Vs Other.NET Types

Chris Burrows explains how the Dynamic object is different  from System.Object.

Demerits of Dynamic objects

There are some current limitations of Dynamic object, like Extension methods cannot be looked up through a Dynamic object. Check out Sam Ng’s post on limitations and what dynamic objects does not do.