Block Syntax for Python

Sunday February 05, 2006

If you can't have the Python syntax you love, love the Python syntax you have

So, apparently, someone proposed this in #twisted yesterday:

def foo():
@x.doSomethingDeferred().addCallback
def something(result):
return result.stuff()
@something.addErrback
def somethingElse(f):
err = f.trap(FooError)
handle(err)
return retry()
return something


I wasn't there to hear it, and I am told that they were shouted down because it is so obviously a horrible idea.

I don't think that it's a horrible idea. I think it is awesome.

It had never before occurred to me that decorators could be used to implement what is almost (but not quite) block syntax for Python. Since block syntax is my all-time highest priority for Python syntax, the fact that this moves things one step closer makes me happy.

In fact, I'd go so far as to say that I'd like to propose that Deferreds gain a few extra features so that you can spell it in a slightly more expressive way:

def foo():
@x.doSomethingDeferred()
def something(result):
return result.stuff()
@something.Except(FooError)
def somethingElse(err):
handle(err)
return retry()
return something


This idiom effectively turns @-at-function-scope into a symbol meaning "do something asynchronous". Hooray! The only reaction I've heard to this so far is JP and Itamar, both calling for my immediate assassination. I'm sure that will be a popular sentiment among Twisted developers. Anyone else who doesn't think I should be killed for echoing this proposal, though?


Update: The first example I posted is a syntax error - due to a misfeature of decorators that, ironically enough, another Twisted developer objected to when it was introduced. As this is a horrible language abuse to improve readability rather than to some other end, I'm not sure I could seriously argue that the idiom should be @apply(lambda: x.doSomethingDeferred().addCallback). I suppose I'll have to go back to getting some real work done today instead...