Braindead Boo Embedding

I’ve got to admit, I’ve got my reservations about Boo.  There’s the take-up question, which wasn’t a big deal before the DLR came striding into town, but is much more important now that there are other ways to skin this particular cat.  Then there’s the extensible syntax, which is one of the most powerful shotguns I’ve ever seen.  They’ve even helpfully set it up to point at your foot by default.

Fact remains, I’ve just done some work for the Castle project that uses Boo for its DSL.  Again, I’ve gone for the “just get it working” approach, so I thought it’d be useful to see this and compare it against the Python version.  Here’s the bootstrap code:

namespace SolutionTransform {
    using System;

    public class Program {
        public static SolutionFile GetSolutionFile(string path)
            return new SolutionFile(path, path.FileContent());

        public static void Main(string[] args)
            if (args.Length < 2) {
                Console.WriteLine("Usage:  SolutionTransform <scriptPath> <solutionPath>");
            } else
                var interpreter = new Boo.Lang.Interpreter.InteractiveInterpreter2();
                interpreter.SetValue("solution", GetSolutionFile(args[1]));
                var script = args[0].FileContent();
                var context = interpreter.Eval(script);
                foreach (var e in context.Errors)

Couple of interesting things to note:

  • Boo doesn’t believe in convenience methods.  You want to read a file, you do it yourself.  I’d argue this is good design.
  • There’s no concept of “script scope” separate from an execution engine.  In practice, this is a consequence of the DLR supporting multiple languages whilst Boo just has to support itself.
  • Boo doesn’t report compilation errors to the console by default.  This is a bit of a gotcha, but not really an issue in non-braindead scenarios.

Ultimately, there isn’t really a “better” to be found here, although personally I hope that Boo supports the DLR in future, which would make swapping between languages easier.  It’d probably also promote takeup of Boo.  The question is whether or not those benefits would be worth the extremely large effort required.

The most interesting point, for me, is the script scope differences.  It highlights a difficulty with the Single Responsibility Principle: what “one thing” means is dependent on context.  I’m sure the developers of Boo think that the interpreter implements SRP, but the fact remains that the DLR has managed to split out a responsibility from it.

Now let’s take a look at the script.

import SolutionTransform
import System.Text.RegularExpressions

    {l|Regex.Replace(l, "-vs2008", "-Silverlight", RegexOptions.IgnoreCase)}, # rename rule
    StandardFilters.RegexFilter(["Castle.Core", "Castle.DynamicProxy", "Castle.MicroKernel", "Castle.Windsor"]), 

# This script is the script for converting a castle solution to the corresponding castle silverlight solution

Now, I think this is inarguably more elegant than the IronPython version around the import statements.  This is a consequence of Boo being a .NET language, rather than a replication of CPython’s semantics integrated with .NET.  On the other hand, there’s a couple of things I don’t like.  One is the lambda syntax.  Do we really need another one?  Boo is a python-like language, and there’s nothing wrong with Python’s syntax here.  The other is the RegexFilter function: it takes an non-generic IEnumerable because Boo won’t just try tacking a .Cast<string> onto the end.  IronPython gets this right.  This is probably a consequence of Boo’s optional static typing.

How you feel about Boo probably comes down to how you feel about the syntax extensibility.  Personally, I’ve never seen a Boo DSL that was well documented and as a friend of mine recently said “A DSL is no substitute for an FAQ.”.

Technorati Tags: ,,

Published by

Julian Birch

Full time dad, does a bit of coding on the side.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s