C# Application Markup Language (CSAML):
An Evolutionary Leap
by Charles Petzold
Several weeks ago, Microsoft Corporation began a limited circulation of
a specification and beta compiler for the new C# Application Markup
Language or CSAML (sometimes pronounced “scammel”), and I’m pleased to
say I find it fascinating. This merging of C# and XML is an important
evolutionary leap for both standards, and represents a profound advance
in the Xmlization of all textual data.
Basically, CSAML is an alternative syntax for C# based on XML and, more
specifically, on XAML, the Extensible Application Markup Language that
plays such an important role in the forthcoming WinFX and the Windows
Presentation Foundation. In particular, CSAML makes uses of the XAML
“property element” syntax for denoting complex statements.
My new book Programming in the Key of CSAML is expected to
be available early in 2007. For now, I want to show you just a few
examples that will let you savor the flavor of this new syntax and be
ready for the big transition when the old C# syntax is phased out in
2008.
Consider the following “old syntax” C# hello-world program:
namespace
MyNamespace
{
public
class
MyClass
{
public
static
void
Main()
{
Console.WriteLine(
"
Hello, C#
"
);
}
}
}
This freeform, unstructured format simply cannot be tolerated in modern
computing environments. Look at the string of words “public static void
Main.” What are those words? How do they relate to each other? There’s
no way to tell. These problems may have been overlooked in the days of
ALGOL, but they can be ignored no longer.
By contrast, check out the clarity that results when equivalent code
is expressed with a syntax that emphasizes precision and
accountability. This is a complete CSAML file with the current
namespace declarations:
<
CsamlFile
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/csaml"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
>
<
NamespaceDeclaration
Identifier
="MyNamespace"
>
<
ClassDeclaration
Identifier
="MyClass"
Access
="Public"
>
<
MethodDeclaration
Identifier
="Main"
Access
="Public"
Modifier
="Static"
ReturnType
="{x:Type void}"
>
<
InvocationExpression
MemberAccess
="System.Console.WriteLine"
>
<
InvocationExpression
.ArgumentList
>
<
Literal
Type
="{x:Type string}"
Value
="Hello, CSAML! "
>
</
InvocationExpression.ArgumentList
>
</
InvocationExpression
>
</
MethodDeclaration
>
</
ClassDeclaration
>
</
NamespaceDeclaration
>
</
CsamlFile
>
As you’ll note, many of these element names are based on the grammar notations used in the C# Language Specification, so every C# programmer is intimately familiar with the names and can begin coding in CSAML immediately.
By relying upon the hierarchical structure that is built into XML,
CSAML is able to forgo the reliance upon curly brackets, square
brackets, and parentheses that so clutters old-syntax C#. As you’ll
note in the file shown above, curly brackets are restricted to their
use in XAML markup extensions, such as x:Type.
In fact, CSAML is able to rid itself of every symbol used in old-syntax C#. For example, consider the following old-syntax C# assignment statement:
A
=
5
*
(B
+
27
*
C);
This statement translates without much fuss into the following chunk of CSAML:
<
ExpressionStatement
>
<
Assignment
LValue
="A"
>
<
Assignment
.Expression
>
<
MultiplicationExpression
>
<
Multiplication
.Multiplier
>
<
Literal
Type
="{x:Type Int32}"
Value
="5"
/>
</
Multiplication.Multiplier
>
<
Multiplication
.Multiplicand
>
<
AdditionExpression
Augend
="B"
>
<
AdditionExpression
.Addend
>
<
Multiplication
.Multiplier
>
<
Literal
Type
="{x:Type Int32}"
Value
="27"
/>
</
Multiplication.Multiplier
>
<
MultiplicationExpression
Multiplicand
="C"
/>
</
AdditionExpression.Addend
>
</
AdditionExpression
>
</
Multiplication.Multiplicand
>
</
MultiplicationExpression
>
</
Assignment.Expression
>
</
Assignment
>
</
ExpressionStatement
>
The advantages of this notation are obvious. Because no parentheses are
required (or allowed), the programmer has composed the CSAML by
carefully considering the problem. Errors are much less likely. The
compiler can become more efficient as well because the statement has,
in effect, been pre-parsed by the programmer.
Here’s another example of perhaps the most notorious syntactical absurdity in all of traditional C# — the for loop:
for
(i
=
0
, j
=
0
; i
<
1000
; i
++
)
if
(IsPrime(i))
j
++
;
In CSAML, that jumble of symbols and semicolons is abandoned for a
structural beauty that can almost induce the modern programmer to weep
with joy:
<
ForLoop
>
<
ForLoop
.Initializer
>
<
StatementExpressionList
>
<
Assignment
LValue
="i"
>
<
Assignment
.Expression
>
<
Literal
Type
="{x:Type Int32}"
Value
="0"
/>
</
Assignment.Expression
>
</
Assignment
>
</
StatementExpressionList
>
</
ForLoop.Initializer
>
<
ForLoop
.Condition
>
<
BooleanExpression
>
<
LessThanExpression
LeftSide
="i"
>
<
LessThanExpression
.RightSide
>
<
Literal
Type
="{x:Type Int32}"
Value
="1000"
/>
</
LessThanExpression.RightSide
>
</
LessThanExpression
>
</
BooleanExpression
>
</
ForLoop.Condition
>
<
ForLoop
.Iterator
>
<
StatementExpressionList
>
<
PreIncrementExpression
Identifier
="i"
/>
</
StatementExpressionList
>
</
ForLoop.Iterator
>
<
ForLoop
.EmbeddedStatement
>
<
IfStatement
>
<
IfStatement
.Condition
>
<
BooleanExpression
>
<
InvocationExpression
MemberAccess
="IsPrime"
>
<
InvocationExpression
.ArgumentList
>
<
Variable
Identifier
="i"
/>
</
InvocationExpression.ArgumentList
>
</
InvocationExpression
>
<
BooleanExpression
>
</
IfStatement.Condition
>
<
IfStatement
.EmbeddedStatement
>
<
StatementList
>
<
PreIncrementExpression
Identifier
="j"
/>
</
StatementList
>
</
IfStatement.EmbeddedStatement
>
</
IfStatement
>
</
ForLoop.EmbeddedStatement
>
</
ForLoop
>
As I write my CSAML book in the months ahead, I’ll be blogging, of course, and sharing with you some of the many features of this new C# syntax, and perhaps even a few shortcuts.
It's certainly an exciting time to be a programmer.