开发者

Ideas on C# DSL syntax

开发者 https://www.devze.com 2022-12-30 07:42 出处:网络
I am thinking about imp开发者_JS百科lementing a templating engine using only the plain C#/.NET 4 syntax with the benefit of static typing.

I am thinking about imp开发者_JS百科lementing a templating engine using only the plain C#/.NET 4 syntax with the benefit of static typing.

Then on top of that templating language we could create Domain Specific Languages (let's say HTML4, XHTML, HTML5, RSS, Atom, Multipart Emails and so on).

One of the best DSLs in .NET 4 (if not only one) is SharpDOM. It implements HTML-specific DSL.

Looking at SharpDOM, I am really impressed of what you can do using .NET (4).

So I believe there are some not-so-well-known ways for implementing custom DSLs in .NET 4. Possibly not as well as in Ruby, but still.

So my question would be: what are the C# (4) specific syntax features that can be used for implementing custom DSLs?

Examples I can think of right now:

// HTML - doesn't look tooo readable :)
div(clas: "head",
  ul(clas: "menu", id: "main-menu", () => {
    foreach(var item in allItems) {
      li(item.Name)
    }
  }) // See how much noise it has with all the closing brackets?
)

// Plain text (Email or something) - probably too simple
Line("Dear {0}", user.Name);
Line("You have been kicked off from this site");

For me it is really hard to come up with the syntax with least amount of noise.

Please NOTE that I am not talking about another language (Boo, IronRuby etc), neither I am not talking about different templating engines (NHaml, Spark, StringTemplate etc).


Are you aware of T4 Templates? While it doesn't allow you to create a DSL, it's certainly nice for generating code or other text-based artifacts, once you've got a model to work from. For example, TextTemplate1.tt:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".thml" #>
<#@ import namespace="System.Collections.Generic" #>

<div class="head">
    <ul class="menu" id="main-menu">
<#
foreach (var item in allItems)
{
#>
        <li><#= item.Name #></li>
<#
}
#>
    </ul>
</div>
<#+
public class DummyItem
{
    public string Name {get;set;}
}

public List<DummyItem> allItems = new List<DummyItem>
                                  {
                                      new DummyItem {Name="Name1"},
                                      new DummyItem {Name="Name2"},
                                  };
#>

This quickly produced:

<div class="head">
    <ul class="menu" id="main-menu">
        <li>Name1</li>
        <li>Name2</li>
    </ul>
</div>

Obviously, you would have to get your model into the system some other way than creating a dummy class!


I would guess you are familiar with Martin Fowlers DSL book, but if not definitely look at it. It does not contain anything specific to C# 4.0, but has some general patterns for internal DSLs which you could use. Also look at how generic types and type inference works in C#, LINQ might be a good example of using advanced language features to implement a DSL. In the LINQ stuff should also be some AST manipulation, which might interest you as well.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号