XAML is for tools

There is quite a bit of discussion internally and externally about the role of XAML in WinFX development.  One of the main questions is "Why would I use XAML instead of C# or VB?"

Simply put, "Sparkle", "Cider" and other design tools provide the main justification for the use of XAML.  Previous efforts such as the WinForms designer have shown that using an imperative style programming language as a serialization mechanism is just asking for trouble...especially if the developer hand modifies any of the generated code.  The problem is the tool must reason about the code, basically figure out its intent, and that is hard given a general programming language.  Declarative languages like XML and HTML can be designed to be more regular and less expressive than something like C++ (see syntactic sugar), but as a result easier for the tool to completely undertstand (HTML hasn't been ideal for this either, but I would argue that is largely the legacy of the original irregular nature of the HTML language (mostly fixed by XHTML), and its chaotic evolution by the browser warriors of the late 90s.)

XAML has been designed with tools in mind from the beginning.  In fact, in the beginning there was a strong tension between toolability and hand-editing of XAML, but in the last 12 months this has been generally resolved in favor of toolability (thanks Chuck!).   For example, XAML eschewed a CSS-like syntax for Styles in favor of a completely XML based version because it reduced the number of grammars the parsers and serializers needed to deal with (see syntactic sugar).  More recently there has been a drive to remove the other "mini-languages" from the Avalon specific parts of XAML.  In particular just last week the Avalon team removed the mini-languages for transforms and gradients.  Let me give an example from the Sparkle source code.  The ScaleTab of our TransformPanel has some paths with gradients.  The code for one of these used to look like this:

<Path Canvas.Left="2.239542961" Canvas.Top="3.165508" Fill="LinearGradient 0,0 1,1 #FFFFFFFF #FFA9BCD8" Stroke="#FF185175" StrokeThickness="0.5pt" StrokeMiterLimit="4" Data="M 0 0 L 7.83187484741211 0 L 7.83187484741211 7.59562969207764 L 0 7.59562969207764 Z" />

The blue bits are the declaration of the gradient.  The mini-language is the "LinearGradient 0,0 1,1 #FFFFFFFF #FFA9BCD8" string.  Clearly this isn't XML, so some other parser must be involved.  The XAML parsers and serializers work by determining the type of the property (Fill property, type == Brush) and looking up a TypeConverter for that type.  BrushTypeConverter then knows how to convert strings to and from brushes.  In the simplest cases BrushTypeConverter can handle "#FF0000FF" and "Blue" to represent a SolidColorBrush of the color opaque blue (this is in itself a mini-language, more on that later).  In the more complex case, it parses "LinearGradient 0,0 1,1 #FFFFFFFF #FFA9BCD8" and figures out this is a LinearGradientBrush with a start point of {0,0}, and end point of {1,1} with the two gradient stops of the specified colors. Frankly, neither the transform mini-language nor the gradient mini-language are that complex, but they do represent a bunch of additional work for the various parsers (see syntactic sugar), they need to be supported and updated individually as the object model changes, and they've turned out to be source of more than a few bugs (potentially even security issues if your parser is written unmanaged and vulnerable to buffer overruns). 

Removing the mini-language required me to rewrite this section of Sparkle as so:

    <Path Canvas.Left="2.239542961" Canvas.Top="3.165508" Stroke="#FF185175" StrokeThickness="0.5pt" StrokeMiterLimit="4" Data="M 0 0 L 7.83187484741211 0 L 7.83187484741211 7.59562969207764 L 0 7.59562969207764 Z" >
      <Path.Fill>
           <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
             <LinearGradientBrush.GradientStops>
                   <GradientStopCollection >
                     <GradientStop Offset="0" Color="#FFFFFFFF"/>
                      <GradientStop Offset="1" Color="#FFA9BCD8"/>
                  </GradientStopCollection>
             </LinearGradientBrush.GradientStops>
          </LinearGradientBrush>
        </Path.Fill>
  </Path>   

There was considerable angst about this change internally.  These particular mini-languages are not terribly hard for the tools to learn, they make the XAML smaller and easier to hand-edit, and finally the mini-language rule is not completely consistent.  Being able to represent a Brush with "#FF0000FF" or "Blue" is still a mini-language, albeit simpler.  And more damning, my example above still contains the Path.Data mini-language, which we decided not to remove (largely because it bloats the XAML files). 

I think we made the right choice.  Partly this is self-interest on my part as a tool author.  But further, I argue that neither the transform nor the gradient mini-languages were much use.  A real gradient or transform is so complex you can't really visualize it in your head just from reading the code, regardless of whether pulled apart into "full-blown" XAML or just a mini-language.