On Wed, Aug 11, 2010 at 4:17 PM, Greg Ewing
Paul Du Bois wrote:
Perhaps it's the "cocall" keyword that could be removed, rather than "codef"? A revised semantics for "codef" could cause the body to use the most recent PEP revisions's "__cocall__ or __call__" mechanism for all function calls, perhaps at the expense of some runtime efficiency.
Thinking about it overnight, I came to exactly the same conclusion! This is actually the idea I had in mind right back at the beginning.
I think there are some good arguments in favour of it. If cocall sites have to be marked in some way, then when you change your mind about whether a function is a generator or not, you have to track down all the places where the function is called and change them as well.
If that causes the enclosing functions to also become generators, then you have to track down all the calls to them as well, etc. etc. I can envisage this being a major hassle in a large program.
Whereas if we mark the functions instead of the calls, although some changes will still be necessary, there ought to be far fewer of them. Generally one tends to call functions more often than one defines them.
There still has to be some weird way to call cofunctions from regular functions. Changing the single definition of a function from "def" to "codef" means revisiting all the sites which call that function in the body of regular functions, and pushing the change up the stack as you mentioned. I think this is the wrong direction. But, if you want to head that way, why not make calling a cofunction from a function also transparent, and exhaust the iterator when the function is called? Then it never matters which kind of function or cofunction you call from anywhere, you can just magically change the control flow by adding "co" to your "def"s.
Also, it seems to me that changing 'def' into 'codef' is a far less intrusive change than sprinkling some kind of call marker throughout the body. It means we don't have to invent a weird new calling syntax. It also means you can read the function and think about it as normal code instead of having to be aware at every point of what kind of thing you're calling. It's more duck-typish.
Again, marking the points at which your function could be suspended is a very important feature, in my mind. I would stick with explicitly using "yield from" where needed rather than magically hiding it. -Greg