On Sun, Dec 8, 2019 at 2:09 PM Tim Peters <tim.peters@gmail.com> wrote:
[Guido]
> We're not changing next(). It's too fundamental to change even subtly.

Note that `next()` already accepts two arguments (the second is an
optional default in case its iterable argument is exhausted).  Like:

>>> next(iter([]), 42)
42

Which I learned earlier in this thread but still haven't quite internalized. :-)
 
> We might add itertools.first(), but not builtins.first(). This kind of functionality
> is not fundamental but it's easy to get slightly wrong (witness many hasty
>  attempts in these threads).
>
> itertools.first() should be implemented in C, but its semantics should be
> given by this (well, let me see if I can get it right):
>
> def first(it, /, default=None):
>     it = iter(it)
>     try:
>         return next(it)
>     except StopIteration:
>         return default

Or, more succinctly, the body can be replaced by:

   return next(iter(it), default)

What I said. :-)
 
I expect - but don't know - that people who think `first()` is a
trivial use of `next()` have that in mind.  I'd nevertheless like to
see it in `itertools`.

I actually think most people who think first() is a trivial use of next() don't care about what happens when the iterator is empty -- either because they *know* it won't happen (maybe they checked for len(a) == 1 before) or because they *assume* it won't happen (or perhaps because if it's empty their code is already broken or they consider its input invalid and are not yet in the stage of development where they care about input validation).
 
But then functional languages have a long
tradition of supplying all sort of things trivially spelled in terms
of other things, and I believe that tradition is appropriate _in that
context_ (when your view of the world builds on layering functions,
you don't want to stop to write a common boilerplate function no
matter how trivial it is, and neither do functional language readers
want to stop to figure out how _you_ named a common boilerplate
function).

I don't know how functional-minded people think.
 
In other words, in that context, the bar for "building it
in" consists far more of "will it be used?" than "is it difficult or
tricky or long-winded?".

But even if you know about 2-arg next(), the next(iter(it), default) version is not quite trivial to come up with -- you have to remember to put the iter() call in -- but IMO the main problem is that not enough people know about 2-arg next(), and that makes it pass the second bar.

--
--Guido van Rossum (python.org/~guido)