Tim Peters wrote:
Who would this help? Seriously. There's nothing special about a generator to a caller, except that it returns an object that implements the iterator interface.
What matters to the caller is irrelevant here. We're talking about what matters to someone writing or reading the implementation. To those people, there is a VERY big difference between a regular function and a generator-function -- about as big as the difference between a class and a function! In fact, a generator-function is in many ways much more like a class than a function. Calling a generator-function doesn't execute any of the code in its body; instead, it creates an instance of the generator, much like calling a class creates an instance of the class. Calling them "generator classes" and "generator instances" would perhaps be more appropriate, and more suggestive of the way they actually behave. The more I think about this, the more I agree with those who say that overloading the function-definition syntax for defining generators is a bad idea. It seems to make about as much sense as saying that there shouldn't be any special syntax for defining a class -- the header of a class definition should look exactly like a function definition, and to tell the difference you have to look for some subtle clue further down. I suggest dropping the "def" altogether and using: generator foo(args): ... yield x ... Right from the word go, this says loudly and clearly that this thing is *not* a function, it's something else. If you haven't come across generators before, you go and look in the manual to find out what it means. There you're told something like Executing a generator statement creates a special callable object called a generator. Calling a generator creates a generator-instance, which is an iterator object... [...stuff about the "yield" statement...] I think this is going to be easier to document and lead to much less confusion than trying to explain the magic going on when you call something that looks for all the world like a function and it doesn't execute any of the code in it. Explicit is better than implicit! -- Greg Ewing, Computer Science Dept, University of Canterbury, Christchurch, New Zealand To get my email address, please visit my web page: http://www.cosc.canterbury.ac.nz/~greg
Greg Ewing wrote:
I suggest dropping the "def" altogether and using:
generator foo(args): ... yield x ...
+2 -- --- Aahz (@pobox.com) Hugs and backrubs -- I break Rule 6 <*> http://www.rahul.net/aahz/ Androgynous poly kinky vanilla queer het Pythonista I don't really mind a person having the last whine, but I do mind someone else having the last self-righteous whine.
[Greg Ewing]
...
Why is this on Python-Dev? The PEP announcement specifically asked for discussion to occur on the Iterators list, and specifically asked to keep it *off* of Python-Dev. I've been playing along with people who wanted to discuss it on c.l.py instead, as finite time allows, but no way does the discussion belong here.
Hi, On Wed, 20 Jun 2001, Greg Ewing wrote:
I suggest dropping the "def" altogether and using:
generator foo(args): ... yield x ...
Nice idea. We might even think about dropping the 'yield' keyword altogether and using 'return' instead (althought I'm not quite sure it is a good idea; I'm just suggesting it with a personal -0.5). A bientot, Armin.
"GE" == Greg Ewing
writes:
GE> What matters to the caller is irrelevant here. We're talking
GE> about what matters to someone writing or reading the
GE> implementation. To those people, there is a VERY big
GE> difference between a regular function and a
GE> generator-function -- about as big as the difference
GE> between a class and a function!
GE> In fact, a generator-function is in many ways much more
GE> like a class than a function. Calling a generator-function
GE> doesn't execute any of the code in its body; instead, it
GE> creates an instance of the generator, much like calling
GE> a class creates an instance of the class. Calling them
GE> "generator classes" and "generator instances" would
GE> perhaps be more appropriate, and more suggestive of the
GE> way they actually behave.
Thanks Greg, I think you've captured perfectly my discomfort with the
proposal. I'm fine with return being "special" inside a generator,
along with most of the other details of the pep. But it bugs me that
the semantics of calling the thing created by `def' is different
depending on some statement embedded deep in the body of the code.
Think about it from a teaching perspective: You're taught that def
creates a function, perhaps called foo. You know that calling foo
starts execution at the first line in the function block. You know
you can put a print statement on the first line and it will print
something out when the function is called. You know that you can set
a debugger break point at foo's first line and when you call the
function, the debugger will leave you on that first line of code.
But all that changes with a generator! My print statement isn't
executed when I call the function... how weird! Hey, the debugger
doesn't even break on the line when I call the function. Okay, maybe
it's some /other/ foo my program is really calling. So let's hunt
around for other possible foo's that my program might be calling.
Hmm, no dice there. Now I'm really confused because I haven't gotten
to the chapter that says "Now that you know all about functions,
forget most of that if you find a yield statement in the body of the
function, because it's a special kind of function called a generator.
Calling such a special function doesn't execute any code, it just
instantiates a built-in object called a generator object. To get any
of the generator's code to execute, you have to call the generator
object's next() method."
Further, I print out the type of the object returned by calling foo
and I see it's a
Please keep this off Python-Dev. Paul Prescod has already fwd'ed Greg's msg to the Iterators list, and let's keep it there.
barry wrote:
My vote is for a "generator" keyword to introduce the code block of a generator. Makes perfect sense to me, and it will be a strong indication to anybody reading my code that something special is going on. And something special /is/ going on!
agreed. +1 on generator instead of def. (and +0 on suspend instead of yield, but that's me) Cheers /F
Why can't we discuss Python development on python-dev? please-take-replies-to-python-dev-meta-ly y'rs, Jeremy -----Original Message----- From: python-dev-admin@python.org [mailto:python-dev-admin@python.org]On Behalf Of Tim Peters Sent: Wednesday, June 20, 2001 12:42 PM To: Barry A. Warsaw Cc: python-dev@python.org Subject: RE: [Python-Dev] Suggested amendment to PEP 255 Please keep this off Python-Dev. Paul Prescod has already fwd'ed Greg's msg to the Iterators list, and let's keep it there. _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev
[Jeremy Hylton]
Why can't we discuss Python development on python-dev?
You can, but without me in this case. The arguments aren't new (they were discussed on the Iterators list before the PEP was posted), and I don't have time to repeat them on (now three) different forums. The PEP announcement clearly said discussion belonged on the Iterators list, specifically asked that it stay off of Python-Dev, and the PEP Discussion-To field (which I assume Barry filled in -- I did not) reads Discussion-To: python-iterators@lists.sourceforge.net If you want a coherent historic record (I do), that's where this belongs.
Jeremy Hylton wrote:
Why can't we discuss Python development on python-dev?
I'm split on this issue. I understand why Tim wants to have the discussion corralled into a single place; it's also a moderate inconvenience to have to add another mailing list every time a "critical" issue comes up. I think the best compromise is to follow the rules currently in existence for the PEP process, and if one doesn't wish to subscribe to another mailing list, e-mail one's feedback to the PEP author directly and raise bloody hell if the next PEP revision doesn't include a mention of the feedback. -- --- Aahz (@pobox.com) Hugs and backrubs -- I break Rule 6 <*> http://www.rahul.net/aahz/ Androgynous poly kinky vanilla queer het Pythonista I don't really mind a person having the last whine, but I do mind someone else having the last self-righteous whine.
"TP" == Tim Peters
writes:
TP> and the PEP Discussion-To field (which I assume Barry filled TP> in -- I did not) reads Not me. I believe it was in Magnus's original version of the PEP. But I do think that now that the code is in the main CVS trunk, it is appropriate to remove the Discussion-To: header and redirect comments back to python-dev. That may be difficult in practice however. -Barry
The PEP announcement specifically asked for discussion to occur on the Iterators list
Sorry, I missed that - I was paying more attention to the PEP itself than what the announcement said. Going now to subscribe to the iterators list forthwith. Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg@cosc.canterbury.ac.nz +--------------------------------------+
My vote is for a "generator" keyword to introduce the code block of a generator. Makes perfect sense to me, and it will be a strong indication to anybody reading my code that something special is going on. And something special /is/ going on!
An informal poll of PythonLabs indicates a split on this subject, perhaps setting Jeremy up as a Sandra Day O'Conner swing vote. But who said this was a democracy anyway? :)
somewhat-like-my-own-country-of-origin-ly y'rs, -Barry
That's a nice analogy, Ruth Barry Ginsburg; a Supreme Court, which appoints the president, seems a closer fit to Python's dictatorship than some sort of democratic process. I wasn't present for the oral arguments, but I'm sure we all know how Tim Scalia voted and that Guido van Clarence Thomas agreed without comment. I assume, then, that Anthony Kennedy Jr. joined you, although he's often a swing vote, too. Can't wait to hear the report from Nina "Michael Hudson" Totenberg. I was originally happy with the use of def. It's not much of a stretch since the def statement defines a code block that has formal parameters and creates a new scope. I certainly wouldn't be upset if Python ended up using def to define a generator. I appreciate, though, that the definition of a generator may look an awful lot like a function. I can imagine a user reading a module, missing the yield statement, and trying to use the generator as a function. I can't imagine this would happen often. My limited experience with CLU suggests that iterators aren't going to be huge, unwieldy blocks where it's hard to see what the ultimate control flow is. If a confused user treats a generator as a regular function, he or she certainly can't expect it to return anything useful, since all the return statements are bare returns; the expected behavior would be some side-effect on global state, which seems both unlikely and unseemly for an iterator. I'm not sure how hard it will be to explain generators to new users. I expect you would teach functions and iterations via for loop, then explain that there is a special kind of function called a generator that can be used in a for loop. It uses a yield statement instead of a return statement to return values. Not all that hard. If we use a different keyword to introduce them, you'd probably explain them much the same way: A generator is a special kind of function that can be used in a for loop and is defined with generator instead of def. As other people have mentioned, Icon doesn't use special syntax to introduce generators. We might as well look at CLU, too, where a different approach. You can view the CLU Reference Manual at: http://ncstrl.mit.edu/Dienst/UI/2.0/Describe/ncstrl.mit_lcs%2fMIT%2fLCS%2fTR -225 It uses "proc" to introduce a procedure and "iter" to introduce an iterator. See page 72 for the details: http://ncstrl.mit.edu/Dienst/UI/2.0/Page/ncstrl.mit_lcs%2fMIT%2fLCS%2fTR-225 /72 It's a toss up, then between the historical antecedents Icon and CLU. I'd tend to favor a new keyword for generators, but could be talked out of that position. Jeremy
participants (8)
-
aahz@rahul.net
-
Armin Rigo
-
barry@digicool.com
-
Fredrik Lundh
-
Greg Ewing
-
Jeremy Hylton
-
Tim Peters
-
Tim Peters