Thursday, October 12, 2006

Boo + SharpDevelop 2.0 = production software

Recently some contract work I did involved creating an application for converting a "legacy" .txt file into several smaller .pdf files for various reasons that won't be listed here.

Due to the fact that this was going to be used by non-programmers and was a "one-shot" software application, I decided to use .NET 2.0... and Boo.

I really wanted to see how a Boo application would hold up if, instead of a quick hack, I used the normal patterns to build production ready software.

There are some glitches in SharpDevelop 2.0, but to be honest, its a really nice environment for creating and debugging Boo applications. Variables that are created in the scope of a method are given a different highlight color, then, say, assigning a value to a local class member. One annoying thing is that the version of Boo that #develop ships with doesn't support generics; I guess they haven't upgraded the Boo addin in awhile.

Boo didn't really get in my way when I was developing the application: in fact, due to the agile nature of Boo, I could write really terse code that was mostly self-documenting and easily maintained.

I say easily maintained because the client requested a modification to the application, and I was able to easily insert the new (and frighteningly different) functionality into the application codebase with ease.

One thing that I loved was using Boo's anonymous closures. A background worker thread had to frequently update the user interface. If you've used Control.Invoke before, you'll know what a major pain in the ass it is. Still, Boo reduced all the complexity to something as simple and easy to read as this:

1 self.Invoke() do:
2 enableControls()
3 fooBar()
4 setupLabel(true)

Or this:

1 processor.Finished += do:
2 self.Invoke() do:
3 chunkProgress.Close()
4 ThreadPool.QueueUserWorkItem() do:
5 Thread.Sleep(2s)
6 processor.Process()

All in all, it turned out just like a C# application would have -- except that thanks to the various syntactic niceness of Boo, development time went down and productivity went way up.

Still, Boo could be made better -- [property] is experiencing growing pains and should be made into a proper class member level macro, the generator syntax gets terrifying once you go beyond simple iterations, and the Boo parser error messages are strange, hard to read laments about tokens or whatever random crap it spews.


Avish said...

Hey, that sounds like fun.

I recently tried to use Control.Invoke in C#, and being hard into Boo (and some of Ruby) I tried to do it using anonymous methods, like thus:

Invoke(delegate {
txtName.Text = "Something";

Turns out you can't do that in C#, no matter how hard you try: the compiler can't cast 'anonymous method' to 'System.Delegate', and you can't create a delegate for anonymous methods, and... ooof.

Ultimately I had to use named methods which killed all the readability. I'm looking forward to moving to Boo, as soon as Generics are properly supported (they aren't anywhere near that, though).

Bet's On said...

Yeah, that's the pain in the ass I was talking about.

Anonymous methods in C# are really weak compared to how they work in Boo.

colby d. said...

It would have been too simple for Microsoft to have made an InvokeDelegate method which took a void() as a parameter. Fortunately they did provide us with the MethodInvoker class which does the same thing. Not very elegant but it does work.

Invoke(new MethodInvoker(delegate() {
txtName = "Something";

Bet's On said...

I didn't even know about MethodInvoker until this very moment! Some .NET Guru I am. =D

Useful, but I think its a testament to how... unsightly the design of Control.Invoke has turned out to be. :/

Rudy said...

I actually ended up using MethodInvoker too, after fiddling with invoke for some time. And on the plus side, I've been introduced to Boo which I'll have to check out.