Pages

Tuesday, August 22, 2006

Some more remarks on closures in Java (part 2)

One feature they proposed are non-local returns. This feature is well known from Smalltalk and allows a closure to change the control-flow of the enclosing method. In Smalltalk there was a good reason for this feature: Smalltalk had no control-constructs like if-then, for, while etc.

For example let's look at 'if-then' in Smalltalk. It's implemented as a method of the true and false classes. I've translated it her into a Java-like syntax:

abstract class Boolean {
abstract void ifThenElse(void() on_true, void() on_false);
}

class True extends Boolean {
void ifThenElse(void() on_true, void() on_false) {
on_true();
}
}

class False extends Boolean {
void ifThenElse(void() on_true, void() on_false) {
on_false();
}
}

void testIt() {
Boolean ok = new False(); // or True

ok.ifThenElse(() {
... // called if True
},
() {
... // called if False
});
}

While this looks a bit complicated in Java, the Syntax in Smalltalk is a bit different and there you would write

ok ifTrue: [ ... ] ifFalse: [ ... ].

Without some kind of non-local return it would be impossible to return from a method if some condition is true. In most language those non-local returns are unnecessary, simply because they have special control constructs directly defined in the language, but the designers of Smalltalk decided to make it otherwise. And it really had it's advantages... BUT: In Java there already is a 'if-then' construct. And a 'for' and 'while'.

So why add non-local returns to closures? I don't know. Maybe because the proponents are fascinated with Smalltalk and want to have a exact clone? But non-local returns are also not common in functional programming and have nothing to do with closures per se. Languages like Ocaml or Haskell don't have it - because it's simply unnecessary. And if you really need it, you have it: It's called exception handling. You simply throw an 'Return' and catch it at the point you want to return to. This works in Java too.

So non-local returns are:
- mostly unnecessary, because Java already has control constructs
- available if necessary by using throw/catch

You may remark now that using Exceptions requires more writing than a simple return. Sure, but who cares, Java is full of construct which requires more typing then the same constructs in other languages. Also non-local returns aren't 'good practice' because it can create obscure errors especially if it's used to easy. For certain 'dangerous' features it's better if they require a bit more typing so that the programmer have to think if it's really a good idea to do. And a reader of the code would less probable overlook it.

No comments: