[Python-ideas] Delayed Execution via Keyword

Joseph Hackman josephhackman at gmail.com
Sun Feb 19 13:13:02 EST 2017


Thanks for the feedback!

On 19 February 2017 at 11:24, Michel Desmoulin <desmoulinmichel at gmail.com>

> A great proposal, although now I would have to explain to my students
> the subtle difference between:
> res = (print(i * i) for i in range(x))
> print('foo')
> print(res)
> And
> res = delayed [print(i * i) for i in range(x)]
> print('foo')
> all(res)
> They seems doing something similar, but they really don't.
> Overall, I still love it.
> When I read about it, I immidiatly though about how Django handles
> translation in models:
> - define your string in english
> - mark it with ugettext_lazy and NOT ugettext
> - the framework delays the translation until a request comes around with
> data about the user lang
> The proposed featured would solve the problem nicely.
> Although I'm not clear on the result of:
> def stuff(arg=delayed []):
> Does this mean we create a NEW list everytime in the body function ? Or
> just a new one the first time than the reference stays in arg ?
> Because the first behavior would solve a problem Python had with mutable
> default arguments since the begining.  But that would mean the result of
> "delayed []" is a concrete thing we store in arg.

My honest preference would be that the [] is evaluated fresh each time the
function is called.
def stuff(arg=delayed f()):
would result in f() being called every time stuff() is. This seems more
valuable to me than just doing it once when the function is first called.

> The "delayed" keyword sounds a lot like something used in async io, so I
> like "lazy" much more. Not only it is shorter, but it convey the meaning
> of what we are doing better.

I'm fine with either delayed or lazy.

> Talking about async, we need to be clear on what those do:
> a = (await|yield) lazy stuff

a = await lazy stuff # same as await stuff, the await forces the lazy to be
a = yield lazy stuff # yields a lazy expression that will be evaluated when
read, a is still set on the push as usual.

> a = lazy (await|yield) stuff (should it even allowed ?)

a = lazy await stuff # returns a lazy expression that, when evaluated will
await stuff. I know this is dangerous, but I think it fits the pattern and
Python is a 'consenting adults' language. If it attempts to evaluate
outside a coroutine, I'm fine with it raising an exception.I'm also totally
cool with this not being allowed.
a = lazy yield stuff # the generator doesn't yield/pause until a is read
from. see above.

a = (lazy stuff(x) for x in stuff)

a generator that returns lazy expressions that are not executed unless read.

> a = None


> with open(x) as f:
>     a = lazy stuff() # raise IOError
> print(a)

> try:
>     a = lazy stuff() # raise
> except Exception:
>     pass

I think this is one of the best points. My guess is that the exception
should be raised where the expression is evaluated. We're all consenting
adults here, and if you want to cause an uncaught exception somewhere, who
am I to stop you?

a = lazy f'{name}' + stuff(age) # is there a closure where we store
> "name"  and 'age'?

I suggest yes, where possible/reasonable.

I can see a reasonable outcome for most of this, but it must be very clear.
> However, I can see several very important things we need to be taking in
> consederation debugging wise.
> First, if there is an exception in the lazy expression, Python must
> indicate in the stack trace where this expression has been defined and
> where it's evaluated.
> Pdb must also be able to allow easily to step in those in a coherent
> manner.
> Evnetually we also may need to allow this:
> a = lazy stuff
> if a is not lazy:
>     print(a)

I do think that this is probably the best greenfield solution for the
problem. My only strong feeling is that it should be VERY difficult to
'accidentally' inspect a lazy, rather than evaluating it.

> But then lazy can't be used a var name to help with the transition.

Yeah. :(

> One last thing: my vote is not dropping the ":" in front of they keyword.

I don't understand what your meaning is here.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20170219/15321b0b/attachment-0001.html>

More information about the Python-ideas mailing list