
At 05:23 PM 10/21/03 -0700, Guido van Rossum wrote:
Unified semantic principles. I want to be able to explain generator expressions as a shorthand for defining and calling generator functions.
For a technical explanation, I would say, "any name that is not defined by the generator expression itself has the binding that was in effect for that name at the time the generator expression occurs." (Note that this statement is equally true for any other non-lambda expression.) For a non-technical explanation, I wouldn't say anything, because I don't think anybody is going to assume the late-binding behavior, who doesn't already have the mental model that "this is a shortcut for a generator function". IOW, the issue I see here is that if somebody runs into the problem, they need to learn about the free variables and closures concept in order to understand why their code is breaking. But, if it doesn't break, then why do they need to learn that?
Invoking default argument semantics makes the explanation less clean: we would have to go through the trouble of finding all references to fere variables. Do you want globals to be passed via default arguments as well? And what about builtins? (Note that the compiler currently doesn't know the difference.)
This sounds like "if the implementation is hard to explain" grounds, which I agree with in principle. I'm not positive it's that hard to explain, though, mainly because I don't see how anyone would *question* it in the first place. I find it hard to imagine somebody *wanting* changes to the variable bindings to affect an iterator expression, and thus the issue of why that doesn't work should be *much* rarer than the other way around. Past this point I think I'll be duplicating either my or Tim's arguments for this, so I'll leave off now.