[Python-ideas] Another use case for the 'lazy' (aka 'delayed') keyword

David Mertz mertz at gnosis.cx
Tue Feb 28 12:52:27 EST 2017


On Tue, Feb 28, 2017 at 9:30 AM, M.-A. Lemburg <mal at egenix.com> wrote:

> Here's an example similar to OCaml's lazy evaluation, which
> uses a simple lazy proxy object.
> ### OCaml like lazy evaluation
> class Lazy:
>     def __init__(self, code, frame):
>         self.code = code
>         self.globals = frame.f_globals
>         self.locals = frame.f_locals
>     def force(self):
>         return eval(self.code, self.globals, self.locals)
>

This is a nice implementation.

def log(level, b, c):
>     if level > 100:
>         return
>     if isinstance(c, Lazy):
>         c = c.force()
>     print ('%04i: %s' % (level, b % c))
>
> value = 1
> log(1000, 'Hello %i', lazy("expensive(value)"))
> log(10, 'Error %i', lazy("expensive(value)"))
>

I agree this is very explicit.  It's also more code which has a minor smell
to it.  In the hypothetical new construct I think it would look like this:

def log(level, b, c):

    if level <= 100:

        print ('%04i: %s' % (level, b % c))

log(1000, 'Hello %i', delayed expensive(value))

log(10, 'Error %i', delayed expensive(value))


To me the second reads much better.  But indeed there *might be* surprises.
We might access the delayed object somewhere other than in the log()
function (not in this example since it's not named, but in other cases).
Understanding where that happens adds to debugging work.

Where I believe this is more important is for Dask-like code structures.
So perhaps I write:

x = delayed expensive(1,2)

y = delayed expensive(x,7)

z = delayed expensive(x,y)

w = delayed expensive(y,z)

v = delayed expensive(w,x)

print(z)


If I want to concretize `z` I don't want to do all the work of also
concretizing `w` and `v` (but I need to do `x` and `y`).  In your explicit
proxy approach, a lot of extra code is needed here.  But maybe Dask's
spelling is perfectly fine:

from dask import delayed
x = delayed(expensive)(1,2)
y = delayed(expensive)(x,7)
z = delayed(expensive)(x,y)
w = delayed(expensive)(y,z)
v = delayed(expensive)(w,x)
print(z.compute())


-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20170228/caac591c/attachment.html>


More information about the Python-ideas mailing list