Dr. David J. Pearce

Variable Scoping for Try-Catch Blocks in Whiley


A friend of mine was talking about how variable scoping for try-catch blocks in Java really frustrated him sometimes.  Specifically, the problem was related to variables declared inside try blocks not being visible in their catch handlers. The example would go something like this:

int val;
try {
 int tmp = f(); // cannot throw MyException
 val = g(tmp); // throws MyException
} catch(MyException e) {
 log(tmp);
 throw e;
}
return h(val);

This code does not compile because tmp is not in scope inside the catch handler. Of course, we can declare tmp outside the catch handler — but this is mildly annoying because it’s only used within that block!

Anyhow, during the discussion I realised that Whiley doesn’t have this problem because it uses flow typing. In fact, there is no real notion of scoping for local variables. The rule is fairly simple: if the variable definitely has a value then it’s in scope. The above example would then look like this in Whiley:

try:
   tmp = f() // cannot throw MyException
   var = g(tmp) // throws MyException
catch(MyException e):
   log(tmp)
   throw e
// var is in scope
return h(var)

Here, the flow typing system will reason that there is no control-flow branch within the block until after tmp is assigned. Therefore, tmp can be safely used within the catch handler.

Ok, so this particular aspect of flow typing is hardly going to set the world on fire … but I thought it was quite neat!