Re: [RFC] Add is_list(mixed $value): bool to check for list-like arrays
| From: | Nikita Popov | Date: | Tue, 05 Jan 2021 10:01:33 +0000 |
| Subject: | Re: [RFC] Add is_list(mixed $value): bool to check for list-like arrays | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-112757@lists.php.net to get a copy of this message | ||
On Sun, Dec 20, 2020 at 2:43 AM tyson andre <tysonandre775@hotmail.com>
wrote:
> Hi internals,
>
> I've created the RFC https://wiki.php.net/rfc/is_list
>
> This adds a new function
is_list(mixed $value): bool that will
> return
> true
> if the type of $value is array and the array keys are `0 ..
> count($value)-1` in that order.
>
> It's well-known that PHP's array data type is rare
> among programming
> languages
> in that it supports both integer and string keys
> and that iteration order is important and guaranteed.
> (it is used for overlapping use cases - in many other languages, both
> vectors/lists/arrays and hash maps are available)
>
> While it is possible to efficiently check that something is an array,
> that array may still have string keys, not start from 0, have missing
> array offsets,
> or contain out of order keys.
>
> It can be useful to verify that the assumption that array keys are
> consecutive integers is correct,
> both for data that is being passed into a module or for validating data
> before returning it from a module.
> However, because it's currently inconvenient to do that, this has rarely
> been done in my experience.
>
> In performance-sensitive serializers or data encoders, it may also be
> useful to have an efficient check to distinguish lists from associative
> arrays.
> For example, json_encode does this when deciding to serialize a value as
> [0, 1, 2] instead of {“0”:0,“2”:1,“1”:1}
> for arrays depending on the key orders.
>
> Prior email threads/PRs have had others indicate interest in the ability
> to efficiently check
> if a PHP array has sequential ordered keys starting from 0
>
> https://externals.io/message/109760 “Any interest in a list
> type?”
> https://externals.io/message/111744 “Request for couple
> memory optimized
> array improvements”
> Implementation: https://github.com/php/php-src/pull/6070 (some
> discussion
> is in the linked PR it was based on)
>
I probably brought this up in a previous thread, but I think it's worth
considering again here, given recent changes to the RFC:
I think it would make more sense to introduce this as `function
array_is_list(array $array): bool`. That is, a function that only accepts
arrays in the first place and determines whether the given array is a list.
Your RFC does mention this possibility, but I think the argument it makes
against it is not particularly strong, especially given the recent rename.
The argument is that is_array_and_list($array) is shorter than writing out
is_array($array) && array_is_list($array) -- that's still true, but with
the new name, it's really not that much shorter anymore.
On the other hand, is_array($array) && array_is_list($array) cleanly
separates out the two predicates. If we take into account the fact that in
the vast majority of cases we will know a-priori that the input is an
array, just not whether it is a list, making the function
array_is_list($array) is both clearer and more concise.
function foo(array $array) {
assert(array_is_list($array)); // Already know it's an array...
}
if (is_array($value)) {
if (array_is_list($value)) { // Already know it's an array...
return serialize_as_list($value);
} else {
return serialize_as_dict($value);
}
}
Regards,
Nikita