tags:

views:

2084

answers:

9

What technology would you recommend to create a DSL for a Business Rules and Validation Application Block for .NET? And why?

The architecture of the framework is established and proof-tested by a production. I just want to create a .NET processor to transform human-readable rules to a compiled Rule implementations.

The options that I'm aware of are:

Unfortunately none of these approaches provides anything to build more-or-less friendly IDE for editing DSL, given the DSL syntax (which would evolve).

Any ideas or hints?

A: 

If you want to create a friendly IDE that edits the DSLs, make the IDE fully graphical, and compile to .NET objects (or use something like IronPython as a glue language).

If the rules are simple enough, you can implement the entire rule-structure graphically. If the rules are complex enough, "human readability" becomes an impossible goal.

Either way, if a set of .NET classes or IronPython objects that create the intermediary code isn't "human readable" enough, then chances are, you want something more dummy-proof than a grammar.

That said, if you just want to create a simple language that programmers can use to create Business Rules, feel free to use any of the above, and make the syntax minimalistic enough not to need Visual Studio's IDE.

+6  A: 

A graphical language for business rules is not a good idea. I would avoid it Business rules have lots of if checks and loops in them, which don't visualize well.

You're much better off with a textual language for describing business rules.

To get a phenomenial user experience for editing code you need:

  1. A parser with good error recovery
  2. The ability to do incremental re-compilation

Good error recovery allows you to effectively determine programer intent from syntatically incomplete constructs. That's crucial for implementing intellisence.

The ability to do incremental-recompilation gives you the ability to do efficent background compilation in response to user edits.

The easiest way to get good error recovery is to write your parser by hand. That way you can use whatever amount of look ahead, or algrorithmic rules, for figuring out what to do in the presence of syntax errors.

When you use a parser generator to create your parser, you loose a lot of flexibility in dealing with syntax errors. That flexibility makes the difference between a good intellisence expereince and a crapy one. So, I recommend you just write it by hand using recursive descent.

Implementing efficent re-compilation requires you to be able to : 1) Properly break down semantic analysis into phases (for something like C# this would be: first construct namespace and type symbols, then resolve using statements, then resolve base classes, etc). 2) The ability to construct a phase-aware dependency graph 3) Algorithms for processing the dependency graph, and invalidating parts of it in response to user edits

For full-flegged programing language, implementing re-compilation can get really tricky. In your case, because you are describing business rules, it might be much simpiler for you (or if compilation is quick enough you might not even need it).

So, I would start with the parser, and then build intellisence on top of it.

If you can avoid VS integration, I would. Integrating into VS requires A LOT of plumbing, and the interop is likely to cause headaches. There are a few companies that sell windows forms editor controls that you hook your parser up to. That are much easier to integrate with than VS.

Scott Wisniewski
Loops aren't nearly as hard to make graphical as they are to explain to non-programmers. I've written in graphical languages with heavy looping and they're not nearly as bad as you make it sound. Envox CDP for example.For non-coders, the solve means no syntax errors.
If someone is not capable of undetstanding this: foreach (customer in CustomerList) { CalculateFicoScore(customer); }How will they ever be able to understand a graphic representation of it.They hard part with loops is the concept, not the way it's displayed.
Scott Wisniewski
Much of the difficulty with error recovery when using a parser generator arises from ambiguities (including shift-reduce and reduce-reduce conflicts) that LR and LALR parsers handle poorly. The GLR algorithm (as used by MS Oslo) resolves much of this in a natural way.
Bevan
scott: You could write it nicely with F#:customers |> map CalculateFicoScore
Henrik
+5  A: 

Another possibly interesting alternative is to use F# quotations.

Quotations allow you to treat part of the program as data, so you can get the AST, analyze it and translate it to other language or execute it in some non-standard way. Together with the flexibility of F#, you should be able to express many things, so you'd have to develop an internal F# DSL/combinator library for describing the rules and a translator/interpreter for F# quotations to run them.

Not sure how a bussines rule might look like, but you could write something like this:

let rule = <@
  if (exists customer having validEmail) then success
  else require whatever 
@>

I wrote an introduction to this topic on my blog. Unfortunatelly, there have been some big changes in the F# CTP and I haven't yet updated the source code, but it should give you a good idea of what are the possibilities & limitations of this approach.

A good example of DSL is F# unit testing framewrok:

[EDIT] Just to clarify why I think this may be a good approach:

  • If you use Visual Studio for editting the DSLs (and you can use the Shell version with F# installed for free), you'll get a very good editing experience for free. Not only syntax highlighting, but also IntelliSense that'll suggest the possible constructs and also a background type-checking that serves as 'grammar' checker for your DSL.
  • Compared to other approaches this one is perhaps one of the easiest to implement.
  • The only limitation is that you're bounded by the F# syntax. However, designing your own language is really difficult, so this may not be that bad at all. Especially given the flexibility of F#.

[/EDIT]

Hope this helps!

Tomas Petricek
+2  A: 

I'd use Boo, I think it's currently one of the most flexible tools for DSL creation. There's a very good book about the subject. Ayende's and Rodrigo's blogs are good inspiration too.

About the IDE, you could extend SharpDevelop, take a look at this.

Mauricio Scheffer
+2  A: 

JetBrains Meta Programming System

You can define custom language editors and other constraints for any new language, so that working with those DSLs becomes really simple. Domain experts who are not familiar with traditional programming can easily work in MPS with their domain-specific languages using domain-specific terminology.

Stephen Denne
A: 

I'm new to it, but OMeta seems like an ideal tool for developing DSLs. There doesn't seem to be an IDE around it, but the good news is that the "rules" one can write in OMeta are very readable. (And it deals with left-recursion, which is highly cool.)

There are currently OMeta implementations in at least Javascript (very exciting to me) and Python, perhaps others. As for C#, Jeff Moser is working on one, which you can read about on his blog and see over at CodePlex . Good luck.

Alan
+3  A: 

The standard tool for building DSL's seams to be ANTLR - it is a powerful lexer / parser generator with a lot of target languages for compiler output. It has backends for C#, Java, C/C++, Python etc. (see the code generation targets list) and lets you inject custom code into your compiler in your target language easily.

There is also a very powerful IDE (ANTLRWorks) and lots of documentation. (Check out The Defenitive ANTLR Reference from Terrence Parr, the author of ANTLR) For References on who else uses it see the Testimonlals page.

You still need to do most of the plumbing for the IDE yourself, but it should be much easier given the robust compiler framework you will get from ANTLR. This should be the case for most solutions posted here ...

I'm currently using a compiler written with ANTLR to preprocess our own DSL to C/C++ output and am very happy with it. Enough of the advertisement, you should try it for yourself :) Have fun!

VolkA
+8  A: 

Microsoft's next generation application development platform, codenamed Oslo

Makes it easier for people to write things down in ways that make sense for the problem domain they are working in

Oslo seems to consist of a visual design tool named "Quadrant", a modelling language named "M", and the "Oslo" repository (a SQL Server database) storing the rules.

So if I read things correctly, you could define a modelling language in M, use Quadrant to define and edit your validation rules using your own modelling language, and write an application that makes use of the Oslo repository, generating your Business Rules and Validation Application Block for .NET.

Stephen Denne
I've just used this to implement a simple DSL and while the bits are still a bit raw, it does look promising, specially with the intellipad integration.
Bruno Lopes
i've been tinkering with Oslo -- and it's very eye opening.
Leon Bambrick
A: 

Ruby is a great language for creating DSLs. For example Rake is a build script DSL written with Ruby.

With the forthcoming IronRuby it is possible to write scripts that call your C# code directly.

Here's some articles on writing DSLs in Ruby.

Garry Shutler