On Mon, Feb 8, 2021 at 5:15 PM tyson andre <tysonandre...@hotmail.com> wrote: > > Hi Larry Garfield, > > > > Hi Larry Garfield, > > > > > > > > Hi internals, > > > > > > > > > > Voting has started on https://wiki.php.net/rfc/any_all_on_iterable and > > > > > ends on 2021-02-22. > > > > > > > > > > This RFC proposes to add the functions `PHP\iterable\any(iterable > > > > > $input, ?callable $callback = null): bool` and `PHP\iterable\all(...)` > > > > > to PHP's standard library's function set, using the namespace > > > > > preferred > > > > > in the previous straw poll. > > > > > > > > > > There is a primary vote on whether to add the functions, and a > > > > > secondary vote on the name to use within the `PHP\iterable` namespace. > > > > > > > > > > Thanks, > > > > > - Tyson > > > > > -- > > > > > PHP Internals - PHP Runtime Development Mailing List > > > > > To unsubscribe, visit: https://www.php.net/unsub.php > > > > > > > > > > > > Ak! I literally just finished reading it and wanted to note a lack of > > > > clarity on one point. :-) > > > > > > > > The signature of the callback is never specified explicitly. The > > > > ternary is a bit confusing. I assume the signature is > > > > > > > > callable(mixed): bool > > > > > > > > But that's not made explicit. It's also not made explict that omitting > > > > the callable collapses to "is truthy". That's a sensible thing to do, > > > > but it's not stated explicitly anywhere, just inferred from the code > > > > sample. > > > > > > > > I'm not sure if it's safe to clarify at this point as the vote just > > > > started. > > > > > > If there is a callable, it allows `callable(mixed): mixed`, > > > and converts the callable's return value to a boolean. > > > So omitting the callable is the same as passing in the callable `fn($x) > > > => $x`, which is equivalent to `fn($x) => (bool)$x`. > > > This is exactly what the reference implementation would do. > > > > > > I definitely should have clarified it instead of assuming that the > > > reference implementation was clear enough. > > > > > > I clarified this and gave examples because the RFC started a few hours > > > ago and the implementation didn't change. > > > > Oof. I'm glad I asked, because I don't like that at all. If available, > > the callable should be returning bool, not "anything that may be > > truthy/falsy." If you have an explicit function, it should have an > > explicit return type. A truthy check is a reasonable default, but not for > > when you're opting in to specifying the logic. > > > > I am in favor of the RFC, but I will have to consider if that changes my > > vote to No. > > > > --Larry Garfield > > This was a deliberate choice and is consistent with the weak type comparison > behavior of array_filter() and other functions that default to using weak > type checks internally. > > I'd agree that I'd prefer to see callbacks returning booleans in code I'm > reviewing, > but a truthiness check seems more practical and consistent with the rest of > the language > than throwing a TypeError or checking the predicate return value using `!== > true` > > This was made to make PHP more widely accessible and free of surprises. > e.g. `(bool)array_filter($arr, $predicate)` can be safely converted to > `any($arr, $predicate)` without introducing a TypeError or behavior change. > > ``` > php > var_dump(array_filter([-1,0,1], fn($x)=>$x)); > array(2) { > [0]=> > int(-1) > [2]=> > int(1) > } > ``` > > This is the same choice as many other dynamic languages that aren't compiled > ahead of time have made. > > ``` > # python > >>> any([1]) > True > >>> any([0]) > False > # Ruby > irb(main):001:0> [nil].any? > => false > irb(main):002:0> [false].any? > => false > irb(main):003:0> !!0 > => true > irb(main):004:0> [0].any? > => true > # JavaScript > > [0].some(x=>x) > false > > [1].some(x=>x) > true > ``` > > It is currently possible to check if code is passing a callable returning > anything other than a boolean > to functions such as `array_filter()` using a wide variety of static > analyzers/tools, e.g. http://github.com/phan/phan > > ``` > <?php > // Phan emits "PhanTypeMismatchArgumentInternal Argument 2 ($callback) is > (fn) of type Closure(int):int > // but \array_filter() takes callable(mixed):bool|callable(mixed,mixed):bool" > array_filter([1], fn (int $x): int => $x % 3); > ``` > > Thanks, > -Tyson > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php >
For what it is worth, in C++ it is fairly normal to use a convertible to bool type. For instance, having an overload on a < b for iterators can return whatever type it wants, as long as it is contextually convertible to bool. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php