The primitives any()
and all()
are a common part of many programming languages and help in avoiding verbosity or unnecessary abstractions.
Before adding this, I'd like to see what others think about the choice of naming pattern.
I don't find adding a prefix visibly appealing, but the argument for the need for a prefix makes sense to me if php were to add functions such as iterable_reduce()
, iterable_count(array|Traversable|Countable)
, iterable_take(iterable, int $limit)
, etc.
any()
is available by default).https://externals.io/message/111756#111814
The main thing I'm concerned about is that once we start extending this area (I assume that any & all are not going to be the last additions in this space) we will quickly run into function names that are either too generic or outright collide. For example, what if we want to add an iterator-based version of range()? Do we really want to be forced to pull a Python and call it xrange()? That's about as good as real_range()...
As such, I think it's important to prefix these somehow, though I don't care strongly how. Could be iter_all() or iterable_all(). We might even make it iterator_all() if we also adjust other existing iterator_* functions to accept iterables. I'd also be happy with iter\all() or iterable\all(), but that gets us back into namespacing discussions :)
Regards, Nikita
This vote will influence the name choice for the RFC https://wiki.php.net/rfc/any_all_on_iterable
Voting starts on 2020-12-19 and will close on 2020-12-26.
See https://wiki.php.net/rfc/any_all_on_iterable
/** Determines whether any element of the iterable satisfies the predicate. */ function(iterable $input, ?callable $callback = null) { foreach ($input as $v) { if ($callback !== null ? $callback($v) : $v) { return true; } } return false; } /** Determines whether all elements of the iterable satisfy the predicate */ function(iterable $input, ?callable $callback = null) { foreach ($input as $v) { if (!($callback !== null ? $callback($v) : $v)) { return false; } } return true; }
Namespaces such as iter\any()
were not considered because existing core global functions are already in the global namespace, and recent suggestions for adopting namespaces for internal functionality have been unpopular (https://wiki.php.net/rfc/php_namespace_policy)
Using static methods instead of global functions was not considered since it would be impractical to polyfill new functions that get added in future php versions in a standard way. (e.g. IterUtils::all()
)
The prefix iterator_
was not considered. In PHP, Iterator and IteratorAggregate already exist, and classes that implement Traversable must implement either Iterator or IteratorAggregate. The name iterator_
would be misleading for functions that also accept arrays.
iterator_*()
functions, where some accept Traversable
and some accept iterable
.iterator_to_array()
) and others have $iterable.*foo(iterable $iterable, ...)
would make more sense than iterator_foo(iterable $iterator, ...)
Changing other iterator functions such as iterator_apply()
, iterator_count()
, and iterator_to_array()
to accept iterator instead of Traversable(Iterator and IteratorAggregate) is out of the scope of the RFC or straw poll.
iterable_apply()
, iterable_count()
, and iterable_to_array()
functions instead of modifying the existing methods. This would be possible to polyfill, and it would be less likely that code developed for 8.1+ would pass arrays that would be rejected by php 8.0 and older. iterator_apply()
, iterator_count()
, and iterator_to_array()
can be done independently of adding *any()
and *all()
.
0.2: Document why iterator_
was not considered as an option.