Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ideas on C# DSL syntax

I am thinking about implementing 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).

like image 548
Dmytrii Nagirniak Avatar asked Feb 18 '26 15:02

Dmytrii Nagirniak


2 Answers

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!

like image 196
John Saunders Avatar answered Feb 21 '26 05:02

John Saunders


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.

like image 37
Gabriel Ščerbák Avatar answered Feb 21 '26 04:02

Gabriel Ščerbák



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!