“Future threads” in Python
Oh, this is cool. So-called “future
threads” are like a multithreading interpretation of promises in
Python.
Remember that in Scheme we can make a promise:
(define a-promise (delay expr))
We can then be forced to keep that promise:
(force a-promise)
The result of the call to force is the evaluation result
of expr.
Now, of course, Python doesn’t have syntax-level macros and
therefore delayed expression evaluation is impossible. But
delayed execution can be achieved with a function
wrapper:
def delay(fn, *args, **kwargs):
return lambda: apply(fn, args, kwargs)
To force this promise, just call the result of
delay—it’s a procedure that actually makes the function
application. (This is a really trivial implementation; it’s
essentially equivalent to a 0-ary curry on a function, and does not have
the memoizing properties of Scheme’s promises. You get the idea,
though.)
With “future threads” you can make a promise like this, but by the
time you force the promise it might already have been computed!
Clearly this is not what you want in situations where you might not
want the code executed. (It will get run, in its own thread,
immediately.) Example taken from the ASPN article linked above:
A=Future(longRunningFunction, arg1, arg2 ...)
print A() # ← will print the result of
# longRunningFunction(arg1, arg2, ...)
The implementation of Future.__call__() will block on the
completion of the thread, so you should only thunk (call with no args)
the future object when you’re really ready for the result, even if you
have to wait for it.
I think that’s pretty slick.