Industry Best Practice

You may have noticed my posting’s been a touch light recently.  There’s an embarrassingly good reason for this: my computer blew up during the snow.  For one reason and another, it has taken me an absolute age to replace it.  Instead, I’ve been using my wife’s old laptop, which isn’t really up to serious development.  On the other hand, it’s made me a voracious reader.  In particular, I finally read Paul Graham’s love letter to Lisp, which contains a passage that I think sums up why discussions of standardization always leave me feeling uncomfortable.*

I believe this term [industry best practice] was originally used to describe accounting methods and so on. What it means, roughly, is don’t do anything weird.

The problem with gut reactions, of course, is that they’re hard to explain, but I think Paul nailed it right there: I’m not an accountant, and I’ve no interest in behaving like one.  There are, of course, good rational reasons for rejecting standardized practices as limiting.  Of course, none of this is going to help me persuade my auditors to throw away their checklists, but I’d rather have happy developers than an ISO 9001 certification.  And believe it or not, I had one of the latter once…

Anyway, the computer arrives tonight, just in time for Lucid Lynx.  It’s downloading as we speak.  🙂

Technorati Tags:

Decorators, Yadic and Castle Windsor

You’ve probably never heard of Yadic.  It’s the smallest DI container I’ve seen.  I’ve linked directly to the only source file because it’s a good read, even if Google Code can’t do syntax colouring for F#.  It’s more opinionated than a party political conference and has some neat ideas.  One of them is the concept that you can specify that a service be decorated.

Let’s just run through that again: you can take a service and stick a decorator on it.  Now, you may be thinking that you can already do this in most containers, and you can but it’s slightly painful.  You need to rename the original instance, register the new instance under the old name and then set up an explicit dependency for the constructor parameter.  It gets worse if the original registration didn’t have a name.  (Yadic, of course, doesn’t allow you to have multiple implementations of the one service.  I did say it was opinionated…) 

Castle Windsor, the container I know best, already has this feature, but it doesn’t know it.  The interceptors feature provides the same functionality, but ties it to the use of DynamicProxy.  As a consequence, it tends to be seen as an extremely technical aspect of the implementation.  It exposes the “How”, but not the “What” or the “Why”.

It also demonstrates something quite surprising: there’s still room for innovation in the IoC container space.  Containers haven’t changed much in the last five years, but they’re much less of a solved problem than it might appear and there’s still a need for revolutionary thinking.  Obviously, I’ve got form on this, but I don’t think the container of 2020 will look much like the container of 2010.  If any of us are still using statically typed languages, that is…

Postscript: I’ve been telling Christian to blog for some time, but to date he’s only made one post.  Mark Needham has tried a new approach to getting his thinking to a wider audience.  It’s got merits… 🙂

Technorati Tags: ,,

Rob Eisenberg’s Co-routine Trick in Retlang

You really owe it to yourself watch Rob Eisenberg’s amazing MVVM talk and download the source code.  There are so many neat things in this talk it’s hard to know where to start.  Basically, he’s written a short, understandable, piece of code that shows how to develop Silverlight applications in a manner with which an ASP.NET MVC developer like myself can be comfortable.  I really liked the “co-routine trick”, so I thought I would write something explaining it in greater depth.

The basic trick is to use yield return’s “co-routine like” execution form an IEnumerable sequence of what code to run on which thread.  Each action, when it completes, sets up the execution of the next action.  This is a bit disguised in the rest of the talk’s code, so I’m ripping it out to show it directly.  It also more clear with consistent threading model, so I use Retlang fibers to follow the thread of execution.  (You’d get other benefits as well, but this post is long enough as it is.)

First off, I’m going to outline the basic form of the trick, as close to Rob’s original as I can managed.  Then there’s a short program that uses it.  Finally, I’ll show you an alternative version that’s arguably even more elegant.

You’re Going To Like It

So, what does Rob’s IResult look like in Retlang?

public interface IResult {
    void Execute();
    IDisposingExecutor Fiber { get; }
}

So you got some code and a “thread” to run it on.  The example code lower down has the obvious dumb implementation, rather than the Command/Query framework that’s in Rob’s code.  Then the co-routine trick looks like this:

public static class CoroutineTrick {
    public static void Execute(this IEnumerable<IResult> results) {
        var enumerator = results.GetEnumerator();
        Action nextAction = null;
        nextAction = () => {
            if (!enumerator.MoveNext()) {
                return;
            }
            var result = enumerator.Current;
            result.Fiber.Enqueue(() => {
              result.Execute();
              nextAction();
            });
        };
        nextAction();
    }
}

The assignment of nextAction to null is a compiler dodge which I recommend ignoring.  Each call to nextAction advances the iterator* and then enqueues the action on the correct fiber.  Then nextAction is called again on the same fiber as the previous action.  (Rob achieves the this effect in the ResultEnumerator class.)

*It helps to remember that MoveNext needs to be called before accessing the first element.

The Demo

Here’s the rest of the code.  It shows a form, moves the progress bar, does a couple of Thread.Sleeps and exits.  As always, note that the UI is responsive the whole time.

class FormProgressReporter : Form {
    private readonly ProgressBar progressBar;

    public FormProgressReporter() {
        progressBar = new ProgressBar();
        SuspendLayout();
        progressBar.Dock = DockStyle.Fill;
        progressBar.Location = new System.Drawing.Point(0, 0);
        progressBar.Name = "progressBar";
        progressBar.Size = new System.Drawing.Size(292, 266);
        progressBar.TabIndex = 0;
        Controls.Add(progressBar);
        Height = 75;
        Width = 600;
        ResumeLayout();
    }

    public void Report(int nodesProcessed, int nodesEncountered) {
        Text = string.Format("{0}/{1}", nodesProcessed, nodesEncountered);
        SuspendLayout();
        progressBar.Maximum = nodesEncountered;
        progressBar.Value = nodesProcessed;
        ResumeLayout();
    }

    protected override void OnShown(EventArgs e) {
        Actions().Execute();
    }

    IEnumerable<IResult> Actions() {
        yield return Update(10, 100);
        yield return Calculate(() => Thread.Sleep(2000));
        var nodes = 20;
        yield return Update(nodes, 100);
        yield return Calculate(() => {
                                       nodes = 75;
                                       Thread.Sleep(2000);
                                   });
        yield return Update(nodes, 100);
        yield return Calculate(() => {
            nodes = 100;
            Thread.Sleep(2000);
        });
        yield return Update(nodes, 100);
        yield return Calculate(() => Thread.Sleep(1000));
        yield return new Result(() => Hide(), Program.ui);
    }

    IResult Calculate(Action action) {
        return new Result(action, Program.worker);
    }

    IResult Update(int nodesProcessed, int nodesEncountered) {
        return new Result(() => this.Report(nodesProcessed, nodesEncountered), Program.ui);
    }
}

public static class Program
{
    internal static IFiber ui = null;
    internal static IFiber worker = new PoolFiber();

    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        var form = new FormProgressReporter();
        ui = new FormFiber(form, new BatchAndSingleExecutor());

        ui.Start();
        worker.Start();
        form.ShowDialog();
    }
}

class Result : IResult {
    private readonly Action action;
    private readonly IDisposingExecutor fiber;

    public Result(Action action, IDisposingExecutor fiber) {
        this.action = action;
        this.fiber = fiber;
    }

    public void Execute() {
        action();
    }

    public IDisposingExecutor Fiber {
        get { return fiber; }
    }
}

You’ll notice that I’m quite dependent upon static variables, which I hate.  However, the original code also relies on this at the moment, and I wanted to produce something that looked as similar as possible, within the constraints of including the entire thing in a single blog post.  The static dependency is fixable, although you’ll have to lose Rob’s implementation of AsResult via extension methods.

Using Sensible Defaults

The code above is a quick hack to demonstrate the idea, but once you understand it there’s even more that can be done.  You could, for instance, modify the code to always execute the MoveNext on a specific fiber.  This could actually be quite elegant: you could always assume code between “yield return”s was on the UI thread (or never).  Here’s how it could look like that:

public static void Execute(this IEnumerable<Action> results, 
IDisposingExecutor worker, IDisposingExecutor ui) { var enumerator = results.GetEnumerator(); Action nextAction = null; nextAction = () => { if (enumerator.MoveNext()) { var command = enumerator.Current; worker.Enqueue(() => { command(); ui.Enqueue(nextAction); }); } }; ui.Enqueue(nextAction); }

At the loss of some flexibility, we’ve now got something that runs yield return actions on worker threads, but everything else on the UI thread.  (A single UI thread is a reasonable assumption most of the time.)  The actions code would then read:

IEnumerable<Action> Actions2() {
    Report(10, 100);
    yield return () => Thread.Sleep(2000);
    var nodes = 20;
    Report(nodes, 100);
    yield return () => {
        nodes = 75;
        Thread.Sleep(2000);
    };
    Report(nodes, 100);
    yield return () => {
        nodes = 100;
        Thread.Sleep(2000);
    };
    Report(nodes, 100);
    yield return () => Thread.Sleep(1000);
    Hide();
}

This model looks even more like we’re using continuations, and we no longer need specialized types.  We might still want them: Rob’s framework mixes this in with its command/query infrastructure.  The beauty of this is: you don’t have to choose.  There’s nothing stopping you supporting both solutions within a framework.

Happy Easter.  🙂

Technorati Tags: ,