Re: [Python-Dev] iterator API in Py3.0
At 09:34 AM 3/4/2006 -0800, Anna Ravenscroft wrote:
I think this is a really good point. next() is supposed to get used, by coders, in regular code - so it shouldn't be __next__. I can understand the desire for both forms, although that seems it would clutter things up unnecessarily - particularly if the two do the same thing.
By this argument, we should be using ob.len() instead of len(ob), and ob.iter() instead of iter(ob).
On Sat, Mar 04, 2006 at 03:45:03PM -0500, Phillip J. Eby wrote:
At 09:34 AM 3/4/2006 -0800, Anna Ravenscroft wrote:
I think this is a really good point. next() is supposed to get used, by coders, in regular code - so it shouldn't be __next__. I can understand the desire for both forms, although that seems it would clutter things up unnecessarily - particularly if the two do the same thing.
By this argument, we should be using ob.len() instead of len(ob), and ob.iter() instead of iter(ob).
Yes, I think it'd be more consistent and more object-oriented. After all we've switched from string.split(x, y) to x.split(y)... Oleg. -- Oleg Broytmann http://phd.pp.ru/ phd@phd.pp.ru Programmers don't die, they just GOSUB without RETURN.
At 12:05 AM 3/5/2006 +0300, Oleg Broytmann wrote:
On Sat, Mar 04, 2006 at 03:45:03PM -0500, Phillip J. Eby wrote:
At 09:34 AM 3/4/2006 -0800, Anna Ravenscroft wrote:
I think this is a really good point. next() is supposed to get used, by coders, in regular code - so it shouldn't be __next__. I can understand the desire for both forms, although that seems it would clutter things up unnecessarily - particularly if the two do the same thing.
By this argument, we should be using ob.len() instead of len(ob), and ob.iter() instead of iter(ob).
Yes, I think it'd be more consistent and more object-oriented.
I'm not sure that "more object-oriented" should be equated with "good" in this context, or indeed any context. :) A function is no more or less polymorphic than a method in any case, especially if the function is normally delegating to a slot or special method in any case.
[Anna Ravenscroft]
I think this is a really good point. next() is supposed to get used, by coders, in regular code - so it shouldn't be __next__. I can understand the desire for both forms, although that seems it would clutter things up unnecessarily - particularly if the two do the same thing.
[Phillip Eby]
By this argument, we should be using ob.len() instead of len(ob), and ob.iter() instead of iter(ob).
Hey, no fair misstating her argument and then reducing it to the absurd. We're all aware that __len__ and __iter__ are supported by a wide variety of object types and are accessed through builtin functions provided expressly for that purpose. In contrast, we're all aware that next() applies only iterator objects, that it was designed for both direct and magic invocation, and that there is no corresponding builtin. This conversation is getting goofy. There is no underlying problem to be solved. Essentially, a couple of developers feel irritated by a perceived aberration from a naming convention. To assuage that irritation, they are willing to either 1) inflict pain on direct callers by cluttering the calling code with pairs of double underscores, or 2) add yet another builtin (needlessly bloating the namespace, adding another level of indirection, and burdening execution with an unnecessary global lookup). The cure is worse than the disease. IMO, the appropriate solution is to amend your understanding of the naming convention to only apply to methods whose normal invocation is exclusively magic and not called directly. Raymond
At 04:11 PM 3/4/2006 -0500, Raymond Hettinger wrote:
[Anna Ravenscroft]
I think this is a really good point. next() is supposed to get used, by coders, in regular code - so it shouldn't be __next__. I can understand the desire for both forms, although that seems it would clutter things up unnecessarily - particularly if the two do the same thing.
[Phillip Eby]
By this argument, we should be using ob.len() instead of len(ob), and ob.iter() instead of iter(ob).
Hey, no fair misstating her argument and then reducing it to the absurd. We're all aware that __len__ and __iter__ are supported by a wide variety of object types and are accessed through builtin functions provided expressly for that purpose. In contrast, we're all aware that next() applies only iterator objects, that it was designed for both direct and magic invocation, and that there is no corresponding builtin.
I didn't misstate her argument or reduce it to the absurd. I simply applied that argument consistently to similar features of Python. It's you who is concluding that this results in absurdity; I made no such conclusion. I'm simply pointing out that in 3.0 we should be consistent. Either we should have ob.iter() and ob.len(), or else we should have a builtin next().
This conversation is getting goofy. There is no underlying problem to be solved. Essentially, a couple of developers feel irritated by a perceived aberration from a naming convention. To assuage that irritation, they are willing to either 1) inflict pain on direct callers by cluttering the calling code with pairs of double underscores, or 2) add yet another builtin (needlessly bloating the namespace, adding another level of indirection, and burdening execution with an unnecessary global lookup).
You have it backwards. If those things are so important as to be the deciding factor, we should add .len() and .iter() methods in 3.0 and use them instead of the len() and iter() functions. Personally, I prefer functions to methods for these kinds of language-defined operations, but that has nothing to do with the issue of consistency. As far as I can understand your position, you seem to be arguing that whatever we have now is correct, and therefore changing it would be wrong. That is, since we use .next() now, this is correct by definition and a change to next() + __next__ would therefore be wrong. And *that* is the only "goofy" thing I see going on here. :)
Phillip J. Eby a écrit :
I didn't misstate her argument or reduce it to the absurd. I simply applied that argument consistently to similar features of Python. It's you who is concluding that this results in absurdity; I made no such conclusion. I'm simply pointing out that in 3.0 we should be consistent. Either we should have ob.iter() and ob.len(), or else we should have a builtin next().
There is a difference though: a next() builtin would change the state of its argument, what len() ant iter() don't do. I usually prefer methods to functions for operations that modify an object. But then we have setattr and delattr :) I'd say it makes sense to go for practicallity here. Let's keep the next() method as it is, and document this as an exception. The canonical place could be section 3.3 in the language reference, but for some reason, it does not list next() right now... Cheers, BC
Another nice thing about having a next() built-in is that it makes
getting the first item of a generator expression a lot more elegant,
IMHO.
I think this:
next(item for item in items if item > 3)
is a lot clearer than this:
(item for item in items if item > 3).next()
or alternatives that would break this into multiple statements.
[inspired by a recent python-list question]
--
Michael Hoffman
On 3/6/06, Michael Hoffman
Another nice thing about having a next() built-in is that it makes getting the first item of a generator expression a lot more elegant, IMHO.
I think this:
next(item for item in items if item > 3)
is a lot clearer than this:
(item for item in items if item > 3).next()
or alternatives that would break this into multiple statements.
Why is putting everything on a single line considered elegant? -- --Guido van Rossum (home page: http://www.python.org/~guido/)
"Michael Hoffman"
Another nice thing about having a next() built-in is that it makes getting the first item of a generator expression a lot more elegant, I think this: next(item for item in items if item > 3) is a lot clearer than this: (item for item in items if item > 3).next() or alternatives that would break this into multiple statements. [inspired by a recent python-list question]
Yuck. This bug-prone one-liner was an answer to the question: how do I (the OP) get just the first item of items meeting a conditiion instead of all, as with filter, with a one-line expression instead of the obvious for loop. Bad question; bad answer. As I pointed out, this 'solution' raises StopIteration if there is no first valid item. That in turn crashes the program unless one adds more lines to deal with the possible exception. In the same post, I also suggested the OP first define his desired no-item behavior (not answered that I have seen). To me, one-liner-itis can entertain, but also distract from complete, correct coding. Terry Jan Reedy
participants (8)
-
Baptiste Carvello
-
Fredrik Lundh
-
Guido van Rossum
-
Michael Hoffman
-
Oleg Broytmann
-
Phillip J. Eby
-
Raymond Hettinger
-
Terry Reedy