The argument that first(it) and next(it) "look the same" doesn't convince me; if these look the same then all function applications look the same, and that can certainly not have been Meertens' intention. But if everyone thinks that first() should raise, fine, this thread is way too long already (I should have kept it muted :-). On Mon, Dec 9, 2019 at 8:56 PM Tim Peters <tim.peters@gmail.com> wrote:
... Similarly, there is already a spelling of first() (or close enough) that raises: 1-arg next(). If 1-arg first() would also raise, it would fail the rule "similar
[Guido] things should be spelled
similarly, and different things should be spelled differently".
The "... unless you're Dutch" part of the Zen may be at work here ;-) Under your semantics for first(),
first(iterator) next(iterator)
look darned near identical, but act very differently if the iterator is exhausted: the second raises StopIteration, while the former returns None. The alternative proposal is that they both raise an exception if the iterator is exhausted: then they look much the same _and_ act much the same.
Likewise under the alternative if a default is explicitly given to both.
It's true that dict.get(key) returns None too, but (a) that's a method rather than a function; and, (b) `first` and `next` are very closely related to each other, but not to any dict methods; and, (c) next(iterable) and dict.get(key) already look kinda similar but already did quite different things in their respective end cases ("iterator already exhausted" and "key not present").
I am not making this rule up -- it's an old design principle that Lambert Meertens used for ABC, Python's predecessor. It just didn't make it in the Zen of Python, unless you want to interpret "there should be one [...] way to do it" as its spiritual descendant.
Or unless you want to add it now as the mysterious 20th aphorism that's been waiting to be revealed :-)
IMO "one raises StopIteration and one raises ValueError" is not enough to warrant two different ones,
Two different _whats_?
nor is "one calls iter() and the other doesn't." But "one raises and the other doesn't" is a significant enough difference (as the example of dict.get() shows).
Well, ya: that's a very significant difference, so doesn't the Meertens Principle suggest that "one raises but the other doesn't" should _not_ look identical?
FWIW I think "first()" is a fine name to get one element from a set --
it's not likez
. the iteration order is a secret, and it's not called "lowest". The other schemes to get one item out of a set in O(1) time will return the same element, since the only sensible way to do it is to iterate and stop after one iteration.
Wholly agreed there. `first()` may or may not be self-evident at first glance, but the meaning becomes obvious and impossible to forget after the first minor effort to grasp it.
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>