java lisp ruby

Continuations and Exceptions

I very often find myself tripping over ‘old’ ideas in software technology and discovering a rich topic that I had no idea even existed. This weeks elephant in the room is the ‘Continuation’ language/compiler feature.

Let’s take a quick look at a simplified version of an example of a continuation that I found to illustrate the point.

irb(main):041:0> def ab
irb(main):042:1>    puts "a"
irb(main):043:1>    callcc { |continuation| return continuation }
irb(main):044:1>    puts "b"
irb(main):045:1> end
=> nil
irb(main):046:0> x = ab()
=> #<Continuation:0xb7c5ee84>
=> nil

The callcc function accepts a closure as an argument. This closure accepts the ‘continuation’ and we immediately return it from the function. The continuation contains all of the state that got us to the point before we exit, variables, stack-frames, the lot. The key is that the continuation is itself a closure and when it is called the code will continue from the next line. I think it’s easy to see that this feature has pitfalls. It’s like a GOTO but without the benefit of having a line number to lookup! This is because on the outside every continuation looks pretty much the same. But this approach does have arguably real tangible benefits in Web servers like Seaside.

So what?

Well it turns out that exceptions in C++ derivative languages are a stupider half-cousin of continuations called: escape continuations. Thinking about it the similarity is striking and not all that surprising. The reason I say they’re stupid though is because exception objects are not re-entrant in the same way as continuations are, and the context that is captured from the exception is defined by the programmer. However, it’s plain to see that the exception handling we have in most modern programming languages like C++, Java, C#, etc are a diluted form of continuation.

So what?

Well I’m not totally convinced of the practicality of continuations in web programming environments, partly because I’m a bit old-school when it comes to performance and those languages that have web-frameworks and support continuations (Smalltalk, Ruby, PHP) are slow-as-molasses. The other reason I’m not keen on the idea of continuations is the practicality of working with them, i.e. they are a variation on the GOTO in that it’s very hard to follow the flow of the program by just looking at it and reading it. But I know that one day I will discover the need to make sparing use of a continuation and be glad that I knew that I could do it.

If the truth is ever told, I think exceptions suffer from the curse of the GOTO as well. And I think the reason for that is partly because the exception mechanism as implemented in Java, C# and C++ is a teensy bit broken. The reason, again, is that the flow of control jumps up the stack to a potentially unknown place. I say unknown because if you write a library that throws an exception and after you release it you change the contract of how that exception is thrown, well then you’re in trouble.

Trouble, that’s what

The catching of exceptions is based on type, and inheritance rules apply, so the inheritance hierarchy of the exception classes you use affects the flow of control. This is clearly the intention since you use the type to differentiate a NullArgumentException and a NullPointerException and how you deal with these will probably require different code. However, if the handling code was the same well then I why couldn’t I catch the base class instead and have one code-block? This is the temptation and the danger because if someone else decides to rejig the exception hierarchy you might not catch the exception you want. Worse still, you might end up catching exceptions you don’t expect and providing incorrect handling code for them.

So what?

Well like Peter Parker says:

Whatever life holds in store for me, I will never forget these words: “With great power comes great responsibility.” This is my gift, my curse. Who am I? I’m Spider-man.

And whilst we may not be Spidey we need to recognize the gifts and curses that 50 years of programming languages has given us … oh, and we should take note about the power/responsibility thing too …


Programmer’s Bladder

Main Entry: pro·gram·mers blad·der
Pronunciation: \ˈprō-ˌgra-mərs ˈbla-dər\
Function: noun phrase
Etymology: Birmingham, Richard Pinchin
Date: circa 1994

1 : A condition that requires the victim to sit at their terminal for extended periods. The condition denies the victim their normal bodily functions until: that fucking thing compiles, or more caffeine is required.


You Suck, I Rock

I guess I’m going beyond the remit of technical blog here and exploring an area best left to people that know more about it than me. So I’ll keep it brief. More and more I’m coming to realise that the ‘them and us’ of software development is a problem. There are many thems and sadly just us, and since we’re obviously the good guys that makes them the bad guys.

What would Al Do?Dale Carengie in his 1933 book writes that very few people ever think of themselves as bad people. Even the really bad ones. Al Capone, arguably the most notorious gangster in history, claimed that he was just providing a public service (effectively saying that the ends justified the means).

The totally unsurprising fact is that almost everybody feels this way about their actions. The reason that we don’t all get along though is that my interests, and hence my actions, are often divergent from yours. Like when you go and commit that change to that function, that I said I didn’t want you to make, you did it because you’re you. And you probably have a very good reason for it. The problem is that I will instantly brand you a jerk, and if I don’t know you very well your jerk-ness will be hard to shrug off. Trust me, you’re pretty much screwed.

The anti-dote to this problem is for me to try and get inside your head and understand why you acted like you did. Maybe then we can find a better, mutually acceptable solution or I can persuade you do it my way. But it’s soooo much harder to do and it sounds really lame. It’s so much easier to write-off perfectly justifiable behaviour as bad and bitch about it for a while.

Welcome Trevor! Trevor is an ex-ex-ex-colleague and he’s nasty. He looks nasty, he talks trash and he has no time for me (or anyone else) because I don’t have a PhD and my IQ is so low that I may as well dribble from the left-side of my mouth and eat through a straw. Trevor is clever. Very clever (almost magical) Trevor. Part of Trevor’s problem was that he was often interrupted during the working day by people who didn’t think about what they were asking. They ended up wasting his time and that really annoyed him. Once I figured this out I made no attempt to have a conversation with him because I knew my opinion was of no interest to him. He just wanted to end whatever conversation we were about to have as quickly as possible. So, I kept our conversations to a minimum and made sure to if possible ask him questions to which he could answer yes or no. Over time it seems that this approach gained me some credits with Trevor. Although we could never be friends some of my fellow ‘retards’ admired the relationship Trevor and I had.

My advice? Hug a Trevor today. It’s worth it.