On Tue, Jul 27, 2010 at 9:38 PM, Carl M. Johnson firstname.lastname@example.org wrote:
What would this code do:
def yield_if_true(x): if x: yield_(x)
def maybe_yield(x): if calculate_property(x): yield_if_true(x) else: return None
When maybe_yield(5) is called different things need to happen depending on whether it’s a function or a generator. If it’s a generator, it shouldn’t execute calculate_property(x) yet, because generators don’t execute their contents until someone says next(maybe_yield(5)) (or maybe_yield(5).next() in Py2.x). On the other hand, if it’s not a generator but a function, then it should run calculate_property right away. You could try starting out as a function and then switching to being a generator if anything that you call has a call to yield_ inside of it, but that strikes me as extremely clumsy and complicated, and it could lead to unpleasant surprises if calculate_property has side-effects.
ISTM there’s no way to do something like PEP-380 without requiring that some special keyword is used to indicate that the def is creating a generator and not creating a function. There other directions to take this besides yield from (for example, we could replace def with gen or some such and give return a special meaning inside a gen statement), but to try to do it without any kind of keyword at the site of the caller means violating "In the face of ambiguity, refuse the temptation to guess.”
Well, in a statically typed language the compiler could figure it out based on the type of the things being called -- "generator-ness" could be propagated by the type system just like "thows a certain expression" is in Java.