The Irrelevant Semantics of Compiled XAML

From newly converted ARC MVP Sam Gentile, I found this interesting post from Drew Marsh about how XAML is compiled:

XAML is indeed a language, but it is never compiled into C# or IL… The truth is, it’s not “compiled” at all. If anything you can say it is “compacted” and that only happens in scenarios where it is turned into a BAML stream. That, however, is an optimization and not a necessity for XAML to work. XAML can be interpreted purely in it’s raw XML text form, using Parser::LoadXml. Even BAML is interpreted, it’s just a far more compact and efficient representation of the object graph than raw XML text.
[Drew Marsh – The XAML Experience]

Given that I just wrote about compiling, I wanted to weigh with a couple of points:

  • First, by definition compilation is a translation from one format to another. Therefore, converting XAML to BAML is a compilation step. The SDM folks have a command line tool for compiling deployment reports from the models in the Architect edition of VSTS. However, I assume what Drew meant here was that XAML isn’t compiled into a directly executable format, so in reality I’m just being picky about the use of the word “compiled”.

  • Second, the fact that the XAML is compiled into an efficient binary representation and then embedded as a resource (as per Rob Relyea) is fascinating from an implementation perspective, but somewhat irrelevant semantically. Drew points out that the BAML is interpreted. With VM environments like CLR, the line between interpreted and compiled blurs considerably. Rob’s post referenced above is based on the PDC 03 XAML bits, and at the time, XAML could be compiled into BAML or IL. However, at the time (20 months ago) Rob guessed that the IL compilation would be cut because the BAML perf was just as good or better, the file size was smaller and localization is easier. In the end, the XAML file is converted into a format the machine can execute – the specific choice of compilers and transformations isn’t particularly interesting from a modeling perspective since it happens automatically.

XAML isn’t the only place where the traditional compiling to executable model is being stretched. In Windows Workflow Foundation, though your workflow is defined as a type, you can actually modify running instances of the workflow. Given that WF supports declaring workflows as C# or XOML (soon to be XAML), I wonder if they are going to go the same route as WPF and eliminate the C#/IL way of declaring workflows. Another interesting example is LINQ and C# 3.0. This is interesting because you can use LINQ directly on in memory data, but when you apply it to database (via DLinq) the LINQ statements are parsed into expression trees then converted into SQL. (Check out this post from Ian Griffiths for deeper coverage of expression trees).

Anyway, it’s late and I realize I’ve written quite a bit to basically say that the definition of “compiled” is pretty blurry at this point and getting blurrier going forward. In the end, it’s much more interesting IMO to focus on the model environment you’re working in (XAML in this case) rather than the details of how that model is translated into the execution environment, unless you’re the one building those translation tools.

Update: I had one other thought on all this. It’s interesting that computing power (CPU + IO bandwidth) have improved to a point where the performance of interpreting BAML at runtime is as fast than executing XAML compiled to IL directly. I certainly wouldn’t have assumed that.

Comments:

A) IL still works You said: I wonder if they are going to go the same route as WPF and eliminate the C#/IL way of declaring workflows RR: WPF still supports using code only (you don't need to ever use XAML if you don't want to...most tools will be built using XAML as the persistance model though). We just don't convert XAML into all IL anymore. I believe WWF/XAML will be similar, but I'm not positive. B) CPU + IO Bandwidth The BAML vs IL question you raise in your UPDATE is an interesting one. When we used to compile XAML to IL, the EXEs were much larger. IL can't be processed as it is downloaded. With BAML, you have a shared amount of code to load it, and repeated baml records to load and discard. So there are a bunch of factors here. Download size of the assembly, streamability of the baml, etc... We were surprised that IL wasn't much faster than BAML. Happily, that allowed us to focus all of our developement, optimizations, testing on one code path, which is a good thing.