On Tue, Dec 10, 2019 at 09:47:08PM -0500, Kyle Stanley wrote:
> I think itertools.first() is a good example of something that would be
> useful and general-purpose enough to be included as a function in
> itertools.
And I think that this discussion demonstrates why it is so hard to
decide which recipes are promoted to full functions. Apologies to
Raymond in advance if I fail to channel him correctly, but I think
his argument will be that this discussion shows why people ought to
implement their own `first` if they need it:
- should it raise on an empty iterable or return a default value?
- if we should raise, what should we raise?
- if the caller doesn't provide a default, should it raise or
return a default default, like None?
- should it work on non-iterators? if yes, the behaviour between
iterators and non-iterators is subtly different and a potential
bug magnet for anyone who calls `first` twice on the same argument
> If even those who have been involved with Python's development since its
> infancy aren't overly familiar with 2-arg next(), how could we reasonably
> expect the average user to be?
I think we're reading too much into Guido's momentary lapse of memory or
slight lack of knowledge, whichever the case may be. Nobody can be
expected to know *everything*, not even Guido, and we're all entitled to
miss the odd thing here or there.
But having said that, `next` is a builtin, not some obscure corner of
some little-used library. Python has a wonderfully effective interactive
interpreter where documentation for `next` is one command away:
py> help(next)
Help on built-in function next in module builtins:
next(...)
next(iterator[, default])
Return the next item from the iterator. If default is given
and the iterator is exhausted, it is returned instead of
raising StopIteration.
If you google for `next`, the very first result mentions the default
right there on the search page, no need to click through:
https://duckduckgo.com/?q=python+next
(Your mileage may vary when using other search engines.)
In addition, the very first post in this thread suggested using the
two-argument form of `next` in their implemention. And there's no
`first` recipe, which suggests that Raymond thought it was too obvious
to bother with. (I'm kinda-sorta in agreement with that, but maybe this
thread shows different.)
I'm not saying that it is an unforgivable failure for a developer to not
know about the 2-arg form of next, that would be ludicrous. But it's not
unreasonable to expect developers to use the 2-arg form of `next`. The
suggested `first` is just a simple composition of two well-known
builtins; saying that nobody can be expected to know the 2-arg form, or
be able to plug the pieces together, is unconvincing.
I'm really on the fence with this one. Comparing the two:
next(iter(obj), default)
itertools.first(obj, default)
I can easily see myself preferring the first as obvious and explicit and
easier than having to import a module. But if I had already imported the
module for other functions, I might prefer the second.
Same reason I will often just write `x**(1/2)` or `pow(x, 0.5)` rather
than `import math; math.sqrt(x)` unless I've already needed the math
module for something else.
--
Steven
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/3IABXDINQEYFP5KKHEN2PXSZ36774AS4/
Code of Conduct: http://python.org/psf/codeofconduct/