<div dir="ltr"><div>Michel-</div><div><br></div><div>Thanks for the feedback! </div><br><div class="gmail_extra"><br><div class="gmail_quote">On 19 February 2017 at 11:24, Michel Desmoulin <span dir="ltr"><<a href="mailto:desmoulinmichel@gmail.com" target="_blank">desmoulinmichel@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">A great proposal, although now I would have to explain to my students<br>
the subtle difference between:<br>
<br>
res = (print(i * i) for i in range(x))<br>
print('foo')<br>
print(res)<br>
<br>
And<br>
<br>
res = delayed [print(i * i) for i in range(x)]<br>
print('foo')<br>
all(res)<br>
<br>
They seems doing something similar, but they really don't.<br>
<br>
Overall, I still love it.<br>
<br>
When I read about it, I immidiatly though about how Django handles<br>
translation in models:<br>
<br>
- define your string in english<br>
- mark it with ugettext_lazy and NOT ugettext<br>
- the framework delays the translation until a request comes around with<br>
data about the user lang<br>
<br>
The proposed featured would solve the problem nicely.<br>
<br>
Although I'm not clear on the result of:<br>
<br>
def stuff(arg=delayed []):<br>
<br>
Does this mean we create a NEW list everytime in the body function ? Or<br>
just a new one the first time than the reference stays in arg ?<br>
<br>
Because the first behavior would solve a problem Python had with mutable<br>
default arguments since the begining. But that would mean the result of<br>
"delayed []" is a concrete thing we store in arg.<br></blockquote><div><br></div><div>My honest preference would be that the [] is evaluated fresh each time the function is called.</div><div>def stuff(arg=delayed f()):</div><div>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.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
The "delayed" keyword sounds a lot like something used in async io, so I<br>
like "lazy" much more. Not only it is shorter, but it convey the meaning<br>
of what we are doing better.<br></blockquote><div><br></div><div>I'm fine with either delayed or lazy.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Talking about async, we need to be clear on what those do:<br>
<br>
a = (await|yield) lazy stuff<br></blockquote><div><br></div><div>suggestion: </div><div>a = await lazy stuff # same as await stuff, the await forces the lazy to be evaluated.</div><div>a = yield lazy stuff # yields a lazy expression that will be evaluated when read, a is still set on the push as usual.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
a = lazy (await|yield) stuff (should it even allowed ?)<br></blockquote><div><br></div><div>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.</div><div>a = lazy yield stuff # the generator doesn't yield/pause until a is read from. see above.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
a = (lazy stuff(x) for x in stuff)<br></blockquote><div><br></div><div>a generator that returns lazy expressions that are not executed unless read.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
a = None<br></blockquote><div><br></div><div>?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
with open(x) as f:<br>
a = lazy stuff() # raise IOError<br>
print(a) </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
try:<br>
a = lazy stuff() # raise<br>
except Exception:<br>
pass<br></blockquote><div><br></div><div>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?</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
a = lazy f'{name}' + stuff(age) # is there a closure where we store<br>
"name" and 'age'?<br></blockquote><div><br></div><div>I suggest yes, where possible/reasonable.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I can see a reasonable outcome for most of this, but it must be very clear.<br>
<br>
However, I can see several very important things we need to be taking in<br>
consederation debugging wise.<br>
<br>
First, if there is an exception in the lazy expression, Python must<br>
indicate in the stack trace where this expression has been defined and<br>
where it's evaluated.<br>
<br>
Pdb must also be able to allow easily to step in those in a coherent manner.<br>
<br>
Evnetually we also may need to allow this:<br>
<br>
a = lazy stuff<br>
if a is not lazy:<br>
print(a)<br></blockquote><div><br></div><div>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.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
But then lazy can't be used a var name to help with the transition.<br></blockquote><div><br></div><div>Yeah. :(</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
One last thing: my vote is not dropping the ":" in front of they keyword.</blockquote><div><br></div><div>I don't understand what your meaning is here. </div></div><br></div></div>