Building Dynamic Types in C# using IronPython

I have created a small routine that allows you to use the IronPython runtime to create dynamic Types without requiring you to write any Python code.

The normal use case for IronPython in C# requires you to provide the IronPython runtime with some source code files, which will essentially eval and return to you a context which you can interact with dynamically. With some help on the forums I was able to find a way to provide an IronPython AST to the runtime instead of source code. This will be very useful for MetaSharp, since I already have a lot of mechanisms for creating an AST I will only need to simply create a transformer that will change an existing AST into IronPython AST and you can suddenly compile any DSL into arbitrarily complex object hierarchies at runtime.

One of the reasons for this is that I want to create a language workbench tool, where you can experiment with your transformations dynamically without having to recompile in the traditional sense. Also, it just gives you more options at runtime. This should be very handy.

Here is an example of what I’m talking about. My example code is very simple, create a class that implements a simple .net interface then create an instance of that class and call it’s method. Here is the actual python version:

#sample.py
from ConsoleApplication4 import IExample

class Example(IExample):
    def Do(self):
        return "hello python"

Executing and calling this at runtime in C# is quite easy to do out of the box actually.

var runtime = Python.CreateRuntime();
runtime.LoadAssembly(typeof(IExample).Assembly);
dynamic python = runtime.UseFile("sample.py");
            
var example = (IExample)python.Example();
Console.WriteLine(example.Do());

The rub here though is that you need that python source file laying around somewhere. Or you could generate code, put it in a temp file and use that instead but nonetheless, the creation of the dynamic object is done by creating python code only. My problem was to figure out how to bypass most of the parsing semantics and to provide an AST directly to the runtime instead of code files. The AST could be created by a MetaSharp transform step.

So instead you can now do this:

var runtime = Python.CreateRuntime();
runtime.LoadAssembly(typeof(IExample).Assembly);

var iexampleImport = typeof(IExample).Import();

var classDefinition = Dlr.Class(
    "Example",
    iexampleImport.ToEnumerable(),
    Dlr.Function(
        "Do",
        Dlr.Self().ToEnumerable(),
        "hello python!".AsConstant().Return()));

dynamic python = runtime.Compile(
    iexampleImport,
    classDefinition);

var example = (IExample)python.Example();
Console.WriteLine(example.Do());

I won’t go into all of the extension methods I created (see link to source at the end) but suffice it to say that the Dlr.Class method is creating a ClassDefinition object. Passing these into the runtime.Compile method is where all of the magic happens.

Figuring out what to do in the Compile extension method was the real hard part. It’s not well documented and some of the side effects are downright bizarre, clearly the API was not intended to be (mis)used in this way.

Fortunately for you, all you have to do is download the file below and you’re off creating dynamic Types using the DLR!

http://cid-dfcd2d88d3fe101c.skydrive.live.com/embedicon.aspx/blog/justnbusiness/DlrCompile.zip

MetaSharp Cloning Error

By the way, if you have cloned the MetaSharp source code in the past and are now experiencing issues pulling you will need to re-create your clone.

There was a lingering CodePlex issue that resulted from the TFS->Mg migration that required some maintenance and as a result it broke all current clones. Going forward there will (hopefully) not be any more such events.

Emerging Languages Conference

I sometimes think about what I would have done with the $5,000 Jeff Atwood gave away to the ScrewTurn Wiki project if he had given it to me instead. Here was what they had to say about using the money.

The grant money is still untouched. It’s not easy to use it. Website hosting fees are fully covered by ads and donations, and there are no other direct expenses to cover. I thought it would be cool to launch a small contest with prizes for the best plugins and/or themes, but that is not easy because of some laws we have here in Italy that render the handling of a contest quite complex.

What would you suggest?

A part of me wonders if it wouldn’t have turned out similarly for me.

But days like this make me realize that I would spend that money to go to Portland and attend the Emerging Languages Conference. I also had the experience of creating my own logos for MetaSharp which I would have happily paid an artist to make for me instead (which I think turned out pretty well despite my not being an artist).

Here it is, btw.

SourceControlFileDownload[1]

Anyway, in addition to sounding really interesting the people of the emerging languages conference apparently have a great sense of humor as well. Here is one of my new favorite quotes taken from the newly created google group:

That’s the beauty of functional programming — you can almost say
anything and make it sound good.  For example, I fully plan to support
higher-order gouda.

– Fogus

I tried to tweet this but Fogus irreverently failed to contain his wit to less that 140 characters. Also… check out coffee script, very cool.