On 15 October 2017 at 05:39, Nick Coghlan <ncogh...@gmail.com> wrote: > On 15 October 2017 at 05:47, Paul Moore <p.f.mo...@gmail.com> wrote: >> >> On 14 October 2017 at 17:50, Nick Coghlan <ncogh...@gmail.com> wrote: >> > If you capture the context eagerly, then there are fewer opportunities >> > to >> > get materially different values from "data = list(iterable)" and "data = >> > iter(context_capturing_iterable)". >> > >> > While that's a valid intent for folks to want to be able to express, I >> > personally think it would be more clearly requested via an expression >> > like >> > "data = iter_in_context(iterable)" rather than having it be implicit in >> > the >> > way generators work (especially since having eager context capture be >> > generator-only behaviour would create an odd discrepancy between >> > generators >> > and other iterators like those in itertools). >> >> OK. I understand the point here - but I'm not sure I see the practical >> use case for iter_in_context. When would something like that be used? > > > Suppose you have some existing code that looks like this: > > results = [calculate_result(a, b) for a, b in data] > > If calculate_result is context dependent in some way (e.g. a & b might be > decimal values), then eager evaluation of "calculate_result(a, b)" will use > the context that's in effect on this line for every result. > > Now, suppose you want to change the code to use lazy evaluation, so that you > don't need to bother calculating any results you don't actually use: > > results = (calculate_result(a, b) for a, b in data) > > In a PEP 550 world, this refactoring now has a side-effect that goes beyond > simply delaying the calculation: since "calculate_result(a, b)" is no longer > executed immediately, it will default to using whatever execution context is > in effect when it actually does get executed, *not* the one that's in effect > on this line. > > A context capturing helper for iterators would let you decide whether or not > that's what you actually wanted by instead writing: > > results = iter_in_context(calculate_result(a, b) for a, b in data) > > Here, "iter_in_context" would indicate explicitly to the reader that > whenever another item is taken from this iterator, the execution context is > going to be temporarily reset back to the way it was on this line. And since > it would be a protocol based iterator-in-iterator-out function, you could > wrap it around *any* iterator, not just generator-iterator objects.
OK, got it. That sounds to me like a candidate for a stdlib function (either because it's seen as a common requirement, or because it's tricky to get right - or both). The PEP doesn't include it, as far as I can see, though. But I do agree with MAL, it seems wrong to need a helper for this, even though it's a logical consequence of the other semantics I described as intuitive :-( Paul _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/