[RFC] "arrayable" pseudo type hint

  107840
November 19, 2019 22:21 norbert@aimeos.com (Aimeos | Norbert Sendetzky)
Since PHP 7.1, there's the "iterable" pseudo type hint that matches
"array" or "Traversable".

PHP frameworks would profit from support of an "arrayable" pseudo type
hint that matches "array" and all objects that can be used like arrays.

For that, "arrayable" objects have to implement these interfaces:
- ArrayAccess
- Countable
- Traversable (i.e. either Iterator or IteratorAggregate)


Implementing "arrayable" pseudo type, we could pass arrays or all
objects that can be used like arrays to methods and do:

function useArrayable( arrayable $arg ) : arrayable {
    $cnt = count( $arg );
    $value = $arg['key'];
    foreach( $arg as $key => $entry );
    return $arg;
}


Best use cases are:

- Laravel Collection
(https://github.com/laravel/framework/blob/6.x/src/Illuminate/Support/Collection.php)

- Aimeos Map (https://github.com/aimeos/map)


No new interface is proposed because we can check if objects implement:

ArrayAccess && Countable && Traversable


Because "array" !== "arrayable", "arrayable objects will not be accepted
by array_* functions and all functions that only use "array" as type
hint for parameters and return types.


This proposal is not obsolete by the implementation of union types (i.e.
array|Traversable) because union data types are types/interfaces
combined by OR. "arrayable" is a combination of OR and AND:

array|ArrayAccess&Countable&Traversable


Also, "arrayable" won't supersede "iterable" because

- "iterable" matches arrays, iterators and generators

- "arrayable" matches arrays and objects that can be used like arrays


"Can be used like arrays" doesn't include support for empty() because it
works for empty arrays but not for "arrayable" objects without elements.
If possible and requested, this may be addressed by another RFC.


As Larry Garfield suggested, this pre-RFC proposes concentrates on the
"arrayable" pseudo type only.

It does NOT discusses that:

- arrayable objects can be converted to arrays (Steven Wade works on an
RFC for a __toArray() magic function)

- ArrayObject or any other arrayable object makes the array_* functions
less relevant in the future

- arrayable objects can be passed to array_* functions in the future
  107853
November 24, 2019 12:53 norbert@aimeos.com (Aimeos | Norbert Sendetzky)
> Since PHP 7.1, there's the "iterable" pseudo type hint that matches > "array" or "Traversable". > > PHP frameworks would profit from support of an "arrayable" pseudo type > hint that matches "array" and all objects that can be used like arrays. > > For that, "arrayable" objects have to implement these interfaces: > - ArrayAccess > - Countable > - Traversable (i.e. either Iterator or IteratorAggregate) > > > Implementing "arrayable" pseudo type, we could pass arrays or all > objects that can be used like arrays to methods and do: > > function useArrayable( arrayable $arg ) : arrayable { > $cnt = count( $arg ); > $value = $arg['key']; > foreach( $arg as $key => $entry ); > return $arg; > }
Implementation is pretty straight forward: https://github.com/aimeos/php-src/commit/8c4f7f1142e20696b9481f4329928a6140eb05fd It also contains is_arrayable() and ReflectionClass::isArrayable() methods. Tests haven't been implemented yet.
  107854
November 24, 2019 15:54 me@jhdxr.com (=?utf-8?b?Q0hVIFpoYW93ZWk=?=)
> This proposal is not obsolete by the implementation of union types (i.e. > array|Traversable) because union data types are types/interfaces > combined by OR. "arrayable" is a combination of OR and AND: > > array|ArrayAccess&Countable&Traversable
True. But it's also easy to implement in userland. Just create a new interface that extends these three interfaces, then union types can work. ```php interface Arrayable extends ArrayAccess, Countable, Traversable {} function array_x (array|Arrayable $arr) {} ``` This is not something that userland cannot implement or very difficult to implement. IMO it will make php more complex if we include this in the core. Actually what you suggested has been totally covered by the future scopes of the union types RFC. If you really want to explore this idea, I think they are worth more attention, instead of this specific case. Regards, CHU Zhaowei
> -----Original Message----- > From: Aimeos | Norbert Sendetzky <norbert@aimeos.com> > Sent: Wednesday, November 20, 2019 6:21 AM > To: internals@lists.php.net > Subject: [PHP-DEV] [RFC] "arrayable" pseudo type hint > > Since PHP 7.1, there's the "iterable" pseudo type hint that matches "array" or > "Traversable". > > PHP frameworks would profit from support of an "arrayable" pseudo type hint > that matches "array" and all objects that can be used like arrays. > > For that, "arrayable" objects have to implement these interfaces: > - ArrayAccess > - Countable > - Traversable (i.e. either Iterator or IteratorAggregate) > > > Implementing "arrayable" pseudo type, we could pass arrays or all objects that > can be used like arrays to methods and do: > > function useArrayable( arrayable $arg ) : arrayable { > $cnt = count( $arg ); > $value = $arg['key']; > foreach( $arg as $key => $entry ); > return $arg; > } > > > Best use cases are: > > - Laravel Collection > (https://github.com/laravel/framework/blob/6.x/src/Illuminate/Support/Collect > ion.php) > > - Aimeos Map (https://github.com/aimeos/map) > > > No new interface is proposed because we can check if objects implement: > > ArrayAccess && Countable && Traversable > > > Because "array" !== "arrayable", "arrayable objects will not be accepted by > array_* functions and all functions that only use "array" as type hint for > parameters and return types. > > > This proposal is not obsolete by the implementation of union types (i.e. > array|Traversable) because union data types are types/interfaces > combined by OR. "arrayable" is a combination of OR and AND: > > array|ArrayAccess&Countable&Traversable > > > Also, "arrayable" won't supersede "iterable" because > > - "iterable" matches arrays, iterators and generators > > - "arrayable" matches arrays and objects that can be used like arrays > > > "Can be used like arrays" doesn't include support for empty() because it works > for empty arrays but not for "arrayable" objects without elements. > If possible and requested, this may be addressed by another RFC. > > > As Larry Garfield suggested, this pre-RFC proposes concentrates on the > "arrayable" pseudo type only. > > It does NOT discusses that: > > - arrayable objects can be converted to arrays (Steven Wade works on an RFC > for a __toArray() magic function) > > - ArrayObject or any other arrayable object makes the array_* functions less > relevant in the future > > - arrayable objects can be passed to array_* functions in the future > > -- > PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: > http://www.php.net/unsub.php >
  107856
November 25, 2019 17:33 andreas@dqxtech.net (Andreas Hennings)
On Sun, 24 Nov 2019 at 16:55, CHU Zhaowei <me@jhdxr.com> wrote:

> > This proposal is not obsolete by the implementation of union types (i.e. > > array|Traversable) because union data types are types/interfaces > > combined by OR. "arrayable" is a combination of OR and AND: > > > > array|ArrayAccess&Countable&Traversable > > True. But it's also easy to implement in userland. Just create a new > interface that extends these three interfaces, then union types can work. > > ```php > interface Arrayable extends ArrayAccess, Countable, Traversable {} > > function array_x (array|Arrayable $arr) {} > ``` > > This is not something that userland cannot implement or very difficult to > implement. IMO it will make php more complex if we include this in the > core. Actually what you suggested has been totally covered by the future > scopes of the union types RFC.
or "intersection types": https://wiki.php.net/rfc/intersection_types
> If you really want to explore this idea, I think they are worth more > attention, instead of this specific case. > > Regards, > CHU Zhaowei > > > -----Original Message----- > > From: Aimeos | Norbert Sendetzky <norbert@aimeos.com> > > Sent: Wednesday, November 20, 2019 6:21 AM > > To: internals@lists.php.net > > Subject: [PHP-DEV] [RFC] "arrayable" pseudo type hint > > > > Since PHP 7.1, there's the "iterable" pseudo type hint that matches > "array" or > > "Traversable". > > > > PHP frameworks would profit from support of an "arrayable" pseudo type > hint > > that matches "array" and all objects that can be used like arrays. > > > > For that, "arrayable" objects have to implement these interfaces: > > - ArrayAccess > > - Countable > > - Traversable (i.e. either Iterator or IteratorAggregate) > > > > > > Implementing "arrayable" pseudo type, we could pass arrays or all > objects that > > can be used like arrays to methods and do: > > > > function useArrayable( arrayable $arg ) : arrayable { > > $cnt = count( $arg ); > > $value = $arg['key']; > > foreach( $arg as $key => $entry ); > > return $arg; > > } > > > > > > Best use cases are: > > > > - Laravel Collection > > ( > https://github.com/laravel/framework/blob/6.x/src/Illuminate/Support/Collect > > ion.php) > > > > - Aimeos Map (https://github.com/aimeos/map) > > > > > > No new interface is proposed because we can check if objects implement: > > > > ArrayAccess && Countable && Traversable > > > > > > Because "array" !== "arrayable", "arrayable objects will not be accepted > by > > array_* functions and all functions that only use "array" as type hint > for > > parameters and return types. > > > > > > This proposal is not obsolete by the implementation of union types (i.e. > > array|Traversable) because union data types are types/interfaces > > combined by OR. "arrayable" is a combination of OR and AND: > > > > array|ArrayAccess&Countable&Traversable > > > > > > Also, "arrayable" won't supersede "iterable" because > > > > - "iterable" matches arrays, iterators and generators > > > > - "arrayable" matches arrays and objects that can be used like arrays > > > > > > "Can be used like arrays" doesn't include support for empty() because it > works > > for empty arrays but not for "arrayable" objects without elements. > > If possible and requested, this may be addressed by another RFC. > > > > > > As Larry Garfield suggested, this pre-RFC proposes concentrates on the > > "arrayable" pseudo type only. > > > > It does NOT discusses that: > > > > - arrayable objects can be converted to arrays (Steven Wade works on an > RFC > > for a __toArray() magic function) > > > > - ArrayObject or any other arrayable object makes the array_* functions > less > > relevant in the future > > > > - arrayable objects can be passed to array_* functions in the future > > > > -- > > PHP Internals - PHP Runtime Development Mailing List To unsubscribe, > visit: > > http://www.php.net/unsub.php > > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >