Dynamic Language Runtime (Part 2) Hello Expressions!

Next post
Previous post

In my previous post I wrote a simple “Hello, world” program. This time, I begin to explore the Expression features of DLR. The code of this post series is at 
http://code.google.com/p/ajcodekatas/ under trunk/Dlr.

First, an Expression in DLR is not a System.Linq.Expression (it was one of my first mistake, in this example, to use the Linq version). DLR has its own implementation, with more methods, at Microsoft.Scripting.Ast. AST is Abstract Syntax Tree: each expression, as in Linq, is a data structure in memory, that represents something like 4, 5+a, or method(arguments…).

Expression DLR class has static method to create expression objects. For example

var expr = Expression.Constant(“I’m a string”);

is the way to create a constant expression. But we need not only constants but variables too:

var expr = Expression.Variable(typeof(string), “foo”);

This statement creates a variable expression, a variable with name foo and type string.

How to invoke an expression? Remember, Expression objects are trees, data structures in memory, not code. The magic of DLR (and Linq, too) is to be able to COMPILE the expression to a delegate, and then, we can invoke it:

expr.Compile().Invoke(); // you can use Invoke with parameters, too

Then, in order to reproduce the “Hello, World” invocation, I wrote in this post sample code a fragment:

// Console.WriteLine("Hello, Method!");
MethodInfo method = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
Expression callExpression = Expression.Call(method, Expression.Constant("Hello Method!"));

I precede the code with a comment containing the equivalent C# code.

Note: we need an Expression.Lambda (in this case, an Action lambda) to create a delegate around an expression. An Action is something to invoke, without returning value (a routine, instead of a function). An Action<string> would receive an string parameter. An Action alone don’t have parameters.

How to use a variable and assign a value to it? This example illustrates the case:

// string x = "Hello, Assign!";
// Console.WriteLine(x);
ParameterExpression x = Expression.Variable(typeof(string), "x");
Expression blockExpression = Expression.Block(
    new ParameterExpression[] { x }, 
    Expression.Assign(x, Expression.Constant("Hello, Assign!")),
    Expression.Call(method, x));

Note that an Expression.Block receives a enumerable of ParameterExpressions, and a param array (variable number of arguments) with Expressions that are the body of the block to execute.

In the next example, I implemented an invalid C# code: a conditional that returns a value:

// x = "Hello";
// if (true)
//     x.ToLower();
MethodInfo toLowerMethod = typeof(string).GetMethod("ToLower", new Type[] {});
ParameterExpression y = Expression.Variable(typeof(string), "y");
ParameterExpression z = Expression.Variable(typeof(string), "z");
Expression blockExpression2 = Expression.Block(
    new ParameterExpression[] { x, y},
    Expression.Assign(x, Expression.Constant("Hello")),
        Expression.Call(x, toLowerMethod),
string result = Expression.Lambda<Func<string>>(blockExpression2).Compile().Invoke();

The first expression in the block is the assignment of constant “Hello” to variable x. Note that any variable is injected as a parameter in the block. That is the way to declare a variable in DLR expression blocks. There is an Expression.Condition with first parameter a boolean expression, an Expression to evaluate if condition is true, an expression to evaluate if condition if false, and the type of the returning value. This kind of condition is like ?: operator in C#.

Main source for this example: “Pro DLR in .NET 4” by Chaur Wu.

Next steps: compile more complicated expressions, binary expressions, IfThenElse expressions, switch expression, and more.

Keep tuned!

Angel “Java” Lopez



2 thoughts on “Dynamic Language Runtime (Part 2) Hello Expressions!

  1. Pingback: Dynamic Language Runtime (Part 3) Binary Expressions « Angel “Java” Lopez on Blog

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