26.2.08
Great minds think alike
One of my favourite examples of the confluence of theory and practice is this pair of papers on exception handling.
Nick Benton and Andrew Kennedy, Exceptional Syntax, Journal of Functional Programming, 11(4):395--410, July 2001.
Richard Carlsson, Björn Gustavsson, Patrik Nyblom Erlang's Exception Handling Revisited, Erlang Workshop, Snowbird, Utah, September 2004.
Both present exactly the same variant on traditional exception handling, but the first paper is driven by proof-theoretic concerns, while the second is entirely pragmatic. (Alas, the symmetry is marred by the fact that Benton and Kennedy also address pragmatics, though one can hardly fault them for that.)
Both papers exhibit deep insight of different kinds, and both are a pleasure to read. A brilliant example of Curry-Howard in action!
Nick Benton and Andrew Kennedy, Exceptional Syntax, Journal of Functional Programming, 11(4):395--410, July 2001.
Richard Carlsson, Björn Gustavsson, Patrik Nyblom Erlang's Exception Handling Revisited, Erlang Workshop, Snowbird, Utah, September 2004.
Both present exactly the same variant on traditional exception handling, but the first paper is driven by proof-theoretic concerns, while the second is entirely pragmatic. (Alas, the symmetry is marred by the fact that Benton and Kennedy also address pragmatics, though one can hardly fault them for that.)
Both papers exhibit deep insight of different kinds, and both are a pleasure to read. A brilliant example of Curry-Howard in action!
Comments:
<< Home
I linked to the official, definitive version of the paper. Anyone at a university will have access to these. If you aren't at a university, it should not be hard to find an unofficial (but perhaps less definitive) version. If anyone wants to leave links to less unofficial versions in a comment, please do so.
Python's try block has an else clause that I think serves the same purpose: http://docs.python.org/ref/try.html
So far as I can see, the 'try' in Python is pretty standard, nothing like the 'try x <= M in P unless H' suggested by Benton and Kennedy. To be precise, Python has nothing that corresponds to the 'in P', which is Benton and Kennedy's innovation.
A translation to python of the example in the first paper would be:
def catpartial(files):
__if not files:
____return ''
__else:
____try:
______f = open(files[0])
____except IOError:
______return catpartial(files[1:])
____else:
______return f.read() + catpartial(files[1:])
def catpartial(files):
__if not files:
____return ''
__else:
____try:
______f = open(files[0])
____except IOError:
______return catpartial(files[1:])
____else:
______return f.read() + catpartial(files[1:])
I see! I had it wrong, and the 'else' part of a Python 'try' clause is indeed like the phrase after 'in' in Benton and Kennedy's notation. Thanks for taking the time to explain this.
My main problem when reading the papers is that I think it is clear that style of syntax for nested exceptions quickly becomes a burden on the source code. So they are sort of fixing something which is inherently broken still at the usability level. I don't know the perfect solution, more's the pity, but perhaps something like D's "scope exit" (http://www.digitalmars.com/d/2.0/exception-safe.html) would be nicer.
Overall, I think the problem is that exceptions are supposed to be a way of extracting one of the (many) dimensions you have to worry about when writing your source code, but you are still stuck with ASCII in a 2D text file, which can't support many "aspects" before turning into heck. So I think the goal of exceptions can't pan out with the classic try/catch/finally.
Overall, I think the problem is that exceptions are supposed to be a way of extracting one of the (many) dimensions you have to worry about when writing your source code, but you are still stuck with ASCII in a 2D text file, which can't support many "aspects" before turning into heck. So I think the goal of exceptions can't pan out with the classic try/catch/finally.
Not sure I like the scope(xyzzy) stuff in D - it looks like a glorified "on error goto" to me. In a language where lambda expressions are just a 'fn' or backslash away, it's very easy to write a function that does the setup and cleanup stuff (with a hole in the middle), and then pass a lambda into that function to specify what is to be done inbetween. This gives you nice, reusable abstractions, instead of a sequence of "do this, and do that on exit, and then do that, and also do that on exit, and ...". See for example how Ruby's standard library File.open lets you pass a block that will be applied on the new file handle, and the file will be closed automatically no matter what happens.
I like D's scope exit more than Ruby's aproach because it doesn't increase the nesting depth of the code. It get's easier to move stuff around, and it's simpler to read. That's the rationale for allowing to declare variables in the middle of a block in C++, which you could always do in C89 by starting a new block.
Post a Comment
<< Home