Grasping the nuclear fourth rail of Python syntax with both hands and holding on for dear life

In Python vs. Ruby: A Battle to The DeathGary Bernhardt wishes for Ruby-style blocks in Python.

The BDFL has already weighed in on anonymous blocks in Python:

If you want anonymous blocks, by all means use Ruby. Python has first-class callables,1 Ruby has anonymous blocks. Pick your favorite, but don’t whine that neither language has both. It ain’t gonna happen.

This seems to imply that first-class callables and anonymous blocks are mutually exclusive language features, but that’s wrong: JavaScript has the ability to pass callables around like anything else, and it has anonymous functions, which can be used just like Ruby’s anonymous blocks. Does that mean JavaScript is better than Python or Ruby? My feelings about Ruby are indifferent with a chance of rain, but I love Python, so I’ve got to ask: are you going to take this lying down, Python?

I’m not sure Python needs full-blown, Ruby-style anonymous blocks. But it might be good enough to be able to use function definitions as r-values, like JavaScript can. (If you’re not already wearing your tinfoil hat, now might be a good time to put it on.)

This would allow asynchronous code to be written in conceptual order (just like in JavaScript):

do_something_asynchronous(param1, param2, (def callback(result):
    do_something_with_result(result)
))

And it would allow encapsulation of lexical scope inside specific iterations of a loop to be used later when an asynchronous call returns (just like in JavaScript):

for item in results:
    (def single_iteration():
        do_something_asynchronous(param1, item, (def callback(result):
            do_something_with_result_and_item(item, result)
        ))
    )(item)

I’ve even had occasion to want that other Python namespace, class, to operate as an r-value:

class MyConverterClass(BaseConverterClass):
    my_converter_type = (class MyConverterType(float):
        def __str__(self): # a custom __str__ method
            return '%0.2f' % self
    )

In these examples I’ve wrapped their inline definitions in Python’s great syntactical equalizer, the parenthesis. It would be even nicer to be able to leave them off, but I’m sure that this syntax would run headlong into Python’s whitespace-based block definitions, and it would be even more of a train-wreck without parentheses.

I’ve also named the defs and classes. It would also be nice to be able to omit the function or class names if they were unneeded (just like in JavaScript). But anonymous functions, a.k.a. lambdas, are the electric third rail of Python syntax, so anonymous classes would be… I dunno, the nuclear fourth rail?

  1. Thanks to Steve for explaining that by “first-class callable,” GvR means functions that can be passed around and assigned to other variables without being executed. He also pointed out that the reason Ruby’s callables aren’t first-class is because optional parentheses in function calls leave no way to refer to a function without calling it, not because of the existence of anonymous blocks. []