I'd like to propose that the Python community standardize on a "deferred" object for asynchronous return values, modeled after the well-thought-out Twisted Deferred class.

With more and more Python libraries implementing asynchronicity (for example Futures -- PEP 3148), it's crucial to have a standard deferred object in place so that code using a single asynchronous reactor can interoperate with different asynchronous libraries.

I think a lot of people don't realize how much cooler and more elegant it is to return a deferred object from an asynchronous function rather than using a generic callback approach (where you pass a function argument to the asynchronous function telling it where to call when the asynchronous operation completes).

While asynchronous systems have been shown to have excellent scalability properties, the callback-based programming style often used in asynchronous programming has been criticized for breaking up the sequential readability of program logic.

This problem is elegantly addressed by using Deferred Generators. Since Python 2.5 added enhanced generators (i.e. the capability for "yield" to return a value), the infrastructure is now in place to allow an asynchronous function to be written in a sequential style, without the use of explicit callbacks.

See the following blog article for a nice write-up on the capability:

http://blog.mekk.waw.pl/archives/14-Twisted-inlineCallbacks-and-deferredGenerator.html

Mekk's Twisted Deferred example:

@defer.inlineCallbacks
def someFunction():
    a = 1
    b = yield deferredReturningFunction(a)
    c = yield anotherDeferredReturningFunction(a, b)
    defer.returnValue(c)

What's cool about this is that between the two yield statements, the Twisted reactor is in control meaning that other pending asynchronous tasks can be attended to or the thread's remaining time slice can be yielded to the kernel, yet this is all accomplished without the use of multi-threading. Another interesting aspect of this approach is that since it leverages on Python's enhanced generators, an exception thrown inside either of the deferred-returning functions will be propagated through to someFunction() where it can be handled with try/except.

Think about what this means -- this sort of emulates the "stackless" design pattern you would expect in Erlang or Stackless Python without leaving standard Python. And it's made possible under the hood by Python Enhanced Generators.

Needless to say, it would be great to see this coolness be part of the standard Python library, instead of having every Python asynchronous library implement its own ad-hoc callback system.

James Yonan
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to