<div dir="ltr"><div class="gmail_default" style="font-family:monospace,monospace"><span style="font-family:arial,sans-serif">On Sun, Oct 8, 2017 at 12:16 AM, Nathaniel Smith </span><span dir="ltr" style="font-family:arial,sans-serif"><<a href="mailto:njs@pobox.com" target="_blank">njs@pobox.com</a>></span><span style="font-family:arial,sans-serif"> wrote:</span><br></div><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><span class="gmail-"><div class="gmail_extra" dir="auto"><div class="gmail_quote">On Oct 7, 2017 12:20, "Koos Zevenhoven" <<a href="mailto:k7hoven@gmail.com" target="_blank">k7hoven@gmail.com</a>> wrote:<blockquote class="gmail-m_-8935789036438109007quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div class="gmail-m_-8935789036438109007elided-text"><div><br></div></div><div><div style="font-family:monospace,monospace">Unfortunately, we actually need a third kind of generator semantics, something like this:</div><div style="font-family:monospace,monospace"><br></div><div style="font-family:monospace,monospace">@contextvars.caller_context</div><div style="font-family:monospace,monospace">def genfunc():</div><div style="font-family:monospace,monospace"> assert cvar.value is the_value</div><div style="font-family:monospace,monospace"> yield</div><div style="font-family:monospace,monospace"> assert cvar.value is the_value</div><div style="font-family:monospace,monospace"><br></div><div style="font-family:monospace,monospace">with cvar.assign(the_value):</div><div style="font-family:monospace,monospace"> gen = genfunc()</div><div style="font-family:monospace,monospace"><br></div><div style="font-family:monospace,monospace">next(gen)</div><div style="font-family:monospace,monospace"><br></div><div style="font-family:monospace,monospace">with cvar.assign(1234567890):</div><div style="font-family:monospace,monospace"> try:</div><div style="font-family:monospace,monospace"> next(gen)</div><div style="font-family:monospace,monospace"> except StopIteration:</div><div style="font-family:monospace,monospace"> pass</div><div style="font-family:monospace,monospace"><br></div><div style="font-family:monospace,monospace">Nick, Yury and I (and Nathaniel, Guido, Jim, ...?) somehow just narrowly missed the reasons for this in discussions related to PEP 550. Perhaps because we had mostly been looking at it from an async angle.</div></div></div></div></div></blockquote></div></div><div dir="auto"><br></div></span><div dir="auto">That's certainly a semantics that one can write down (and it's what the very first version of PEP 550 did), </div></div></blockquote><div><br></div><div><div class="gmail_default" style="font-family:monospace,monospace">I do remember Yury mentioning that the first draft of PEP 550 captured something when the generator function was called. I think I started reading the discussions after that had already been removed, so I don't know exactly what it was. But I doubt that it was *exactly* the above, because PEP 550 uses set and get operations instead of "assignment contexts" like PEP 555 (this one) does. </div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto"><div dir="auto">but why do you say it's needed? What are these reasons that were missed? Do you have a use case?</div><span class="gmail-HOEnZb"><font color="#888888"><div dir="auto"><br></div></font></span></div></blockquote><div><br></div><div><div class="gmail_default" style="font-family:monospace,monospace">Yes, there's a type of use case. When you think of a generator function as a function that returns an iterable of values and you don't care about whether the values are computed lazily or not. In that case, you don't want next() or .send() to affect the context inside the generator.</div><br></div><div><div class="gmail_default" style="font-family:monospace,monospace">In terms of code, we might want this:</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">def values():</div><div class="gmail_default" style="font-family:monospace,monospace"> # compute some values using cvar.value and </div><div class="gmail_default" style="font-family:monospace,monospace"> return a_list_of_values</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">with cvar.assign(something):</div><div class="gmail_default" style="font-family:monospace,monospace"> data = values()</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">datalist = list(data)</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">...to be equivalent to:</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">def values():</div><div class="gmail_default" style="font-family:monospace,monospace"> # compute some values using cvar.value and</div><div class="gmail_default" style="font-family:monospace,monospace"> # yield them one by one</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">with cvar.assign(something):</div><div class="gmail_default" style="font-family:monospace,monospace"> data = values()</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">datalist = list(data)</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">So we don't want the "lazy evaluation" of generators to affect the values "in" the iterable. But I think we had our minds too deep in event loops and chains of coroutines and async generators to realize this.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">Initially, this seems to do the wrong thing in many other cases, but in fact, with the right extension to this behavior, we get the right thing in almost all situtations. We still do need the other generator behaviors described in PEP 555, for async and other uses, but I would probably go as far as making this new one the default. But I kept the decorator syntax for now. </div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">-- Koos</div></div></div><br clear="all"><div><br></div>-- <br><div class="gmail_signature">+ Koos Zevenhoven + <a href="http://twitter.com/k7hoven" target="_blank">http://twitter.com/k7hoven</a> +</div>
</div></div>