I've been blogging previously about how compiler extensions could solve a bunch of issues and how compiler extensions would just represent just another framework.
The reactions to the concept are mixed. Mostly it raises a lot of feelings to the surface. We as developers are really truely attached to our favourite programming language, and we also tend to be really loyal as well. That said and lets get to the point; when we're looking at the evolution of C# for instance, the path Microsoft has taken surely looks a lot like they are writing compiler extensions to solve the issues they want solved.
Anonymous delegates for instance, they are nothing but compiler magic.
Take the following sample:
[code:c#]
ThreadStart threadStart = new ThreadStart(
delegate()
{
Console.WriteLine("Hello from thread #2");
}));
Thread thread = new Thread(threadStart);
thread.Start()
[/code]
If we open the compiled binary in a program like Reflector and take look at what the compiler has actually done:
The compiler generates a method called <Main>b_0() that has the content of the anonymous delegate:
If we set the optimization option i reflector to .net 1.0, we can see the content of the Main() method and what it is actually doing:
[code:c#]
private static void Main(string[] args)
{
ThreadStart threadStart = (CS$<>9__CachedAnonymousMethodDelegate1 != null) ? CS$<>9__CachedAnonymousMethodDelegate1 : (CS$<>9__CachedAnonymousMethodDelegate1 = new ThreadStart(Program.<Main>b__0));
new Thread(threadStart).Start();
}
[/code]
This is just one of many "compiler extensions" Microsoft has up their sleeve themselves. With C# 3.0, Microsoft introduced quite a bit of new language constructs. var, extension methods, Lambda, LINQ, anonymous methods – to name a few. All these features are built upon the .net 2.0 CLR and does not introduce anything new to the runtime, which means that they are all just compile-time magic.
Taking the above sample and making it more C# 3.0:
[code:c#]
var thread = new Thread(
() => Console.WriteLine("Hello from thread #2"));
thread.Start();
[/code]
We take use of the var keyword and lambdas and the code looks a lot better. But opening this in Reflector, targetting CLR 2.0, you'll see what really goes on:
The var keyword is replaced with the actual type, as expected and the lambda expression is expanded to a delegate as expected.
LINQ takes the rewrite to the extreme, consider the following C# 3.0 code:
[code:c#]
var employees = new List<Employee>();
var query = from e in employees
where e.FirstName.StartsWith("A")
select e;
query.ToArray();
[/code]
The expanded version looks like this:
It expands the LINQ into using the fluent interfaces defined for LINQ.
So, where am I going with this. You probably already knew all this. Well, my point is; if Microsoft themselves are pretty much doing compiler extensions today, I do not see why we shouldn't. It is not as scary as one would first think. Compiler extensions could solve a bunch of domain specific problems one is facing and if one did the extensibility correctly, all extensions written would act as just another framework.
Great post!
When I talk about compiler extensibility (mostly in a Boo context) I focus on how it empowers the developers. It will enable us to build more powerful frameworks. This is all about productivity and that can’t be a bad thing.
Another great example on how Microsoft goes around the constraints of their languages when they develop their own frameworks is the library "Contracts" that is a part of .Net 4.0. Here they have created a post compiler plugin to Visual Studio to be able to put in the power they needed. I have two thoughts on that:
1. The Contracts-framework is really powerful!
2. You cannot expect normal developers to go about and create a VS-plugin every time we need a bit more power. That takes alot of time and resources, why not just give us compiler extensibility?
Thanks.
A very good point you got there. It seems that they are having this post-compile approach to a lot these days, it seems like its the same thing that is going on with the business application framework they’ve created for Silverlight; codenamed Alexandria.
I’m waiting for my extensibility options. 🙂 I’ll keep on nagging about it, till its there, even if it takes me 50 years..
I have my reservations due to the following:
I am afraid the mechanism is too abstract, hence people will fear to use them. There are too much magic.
My biggest fear is that any custom compiler extension is code. Code can be lost, and a lost compiler extension would cause a lot of damage.
Any code based on custom extensions will be hard to reuse.
All this is fear, I know, but the problems are no less real. However, the built-in extensions will always be there.
I see your point, but what if the code for compiler extensions were included with the code that needed them, as part of the framework.
I think this boils down to how one structures your project or code. Whenever new stuff is introduced, theres always a risk of abuse. Some developers will always do the wrong thing with the right tools. But I think we should not be limited as developers to increase our creativity and productivity by this fact.