Re: [PHP-DEV] Re: [RFC] "arrayable" pseudo type hint

2020-02-06 Thread Nikita Popov
On Tue, Feb 4, 2020 at 7:40 PM Aimeos | Norbert Sendetzky <
norb...@aimeos.com> wrote:

> Am 04.02.20 um 19:17 schrieb Rowan Tommins:
> > I think Larry's point was that the flexibility of PHP's array type makes
> it
> > really hard to pin down whether a given object is "array-like" or not,
> and
> > which attributes a particular function actually cares about.
>
> What else besides array access, counting and traversing is possible that
> may differ from classes that implement those interfaces?
>
> > A general "intersection type" system might be more useful, because then
> you
> > could require the parts you specifically needed, such as
> > "traversable" or "traversable".
>
> I think that's too complicated and we should make it as easy as possible
> for PHP developers.
>
> Also, there's already an RFC for intersection types but it was never
> adopted: https://wiki.php.net/rfc/intersection_types
>

FWIW, that's an old RFC that predates the current implementation of union
types in PHP 8 by a few years... A new proposal for intersection types
should stand a better chance now, especially as it can mostly reuse the
(relatively involved) technical underpinnings for the union types
implementation.

Nikita


Re: [PHP-DEV] Re: [RFC] "arrayable" pseudo type hint

2020-02-04 Thread Andreas Hennings
On Tue, 4 Feb 2020 at 22:19, Larry Garfield  wrote:

> On Tue, Feb 4, 2020, at 12:40 PM, Aimeos | Norbert Sendetzky wrote:
> > Am 04.02.20 um 19:17 schrieb Rowan Tommins:
> > > I think Larry's point was that the flexibility of PHP's array type
> makes it
> > > really hard to pin down whether a given object is "array-like" or not,
> and
> > > which attributes a particular function actually cares about.
> >
> > What else besides array access, counting and traversing is possible that
> > may differ from classes that implement those interfaces?
> >
> > > A general "intersection type" system might be more useful, because
> then you
> > > could require the parts you specifically needed, such as
> > > "traversable" or "traversable".
> >
> > I think that's too complicated and we should make it as easy as possible
> > for PHP developers.
> >
> > Also, there's already an RFC for intersection types but it was never
> > adopted: https://wiki.php.net/rfc/intersection_types
>
>
> Rowan is exactly right and said it better than I did.
>
> The point is that "I can count() it", "I can foreach() it" and "I can
> bracket it" are three different things; in practice, a given function
> likely only cares about one, maybe two of those at a time.  Adding a type
> for "an object that mimics all of the dumb things arrays do, but now passes
> differently" doesn't strike me as useful; it strikes me as the sort of
> thing I'd reject in a code review if someone tried to do it in user space.
>
> The problem with PHP arrays is that they're not arrays; they're a hash map
> with poor safety, lame error semantics, and some cheats to make them kinda
> sorta look like arrays if you don't look too carefully.  In practice, they
> create more bugs than they fix.
>

There is one good thing about arrays:
They are passed along by-value by default, which gives them similar
qualities as an "immutable" object.
If you pass an array to a function as a parameter which is not
by-reference, you can expect the original array to remain unchanged.
(Objects or referenced variables within that array can still be modified of
course)

A function parameter which allows an object OR an array loses this
advantage.

If I have the choice between \stdClass and array for "unstructured tree of
data", I will always prefer the array.

~~ Andreas


>
> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


Re: [PHP-DEV] Re: [RFC] "arrayable" pseudo type hint

2020-02-04 Thread Larry Garfield
On Tue, Feb 4, 2020, at 12:40 PM, Aimeos | Norbert Sendetzky wrote:
> Am 04.02.20 um 19:17 schrieb Rowan Tommins:
> > I think Larry's point was that the flexibility of PHP's array type makes it
> > really hard to pin down whether a given object is "array-like" or not, and
> > which attributes a particular function actually cares about.
> 
> What else besides array access, counting and traversing is possible that
> may differ from classes that implement those interfaces?
> 
> > A general "intersection type" system might be more useful, because then you
> > could require the parts you specifically needed, such as
> > "traversable" or "traversable".
> 
> I think that's too complicated and we should make it as easy as possible
> for PHP developers.
> 
> Also, there's already an RFC for intersection types but it was never
> adopted: https://wiki.php.net/rfc/intersection_types


Rowan is exactly right and said it better than I did.

The point is that "I can count() it", "I can foreach() it" and "I can bracket 
it" are three different things; in practice, a given function likely only cares 
about one, maybe two of those at a time.  Adding a type for "an object that 
mimics all of the dumb things arrays do, but now passes differently" doesn't 
strike me as useful; it strikes me as the sort of thing I'd reject in a code 
review if someone tried to do it in user space.

The problem with PHP arrays is that they're not arrays; they're a hash map with 
poor safety, lame error semantics, and some cheats to make them kinda sorta 
look like arrays if you don't look too carefully.  In practice, they create 
more bugs than they fix.

Intersection types would be absolutely delightful and I want them for numerous 
reasons.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Re: [RFC] "arrayable" pseudo type hint

2020-02-04 Thread Guilliam Xavier
On Tue, Feb 4, 2020 at 1:48 PM Aimeos | Norbert Sendetzky
 wrote:
>
> [...]
>
> interface Arrayable extends ArrayAccess, Countable, Traversable
> {
> public function toArray() : array;
> }
>
> [...]
>
> If union data types are available and "iterable" is implemented as
> alias, an alias "arrayable" for "array|Arrayable" may be added as well.

About that last point: it would not be possible to have both the
`Arrayable` interface and the `arrayable` reserved word because PHP is
case-insensitive for those things (the same way you cannot declare an
`interface Iterable` because of the `iterable` reserved word,
), so you would need another name (if you want
the alias)

-- 
Guilliam Xavier

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Re: [RFC] "arrayable" pseudo type hint

2020-02-04 Thread Aimeos | Norbert Sendetzky
Am 04.02.20 um 19:17 schrieb Rowan Tommins:
> I think Larry's point was that the flexibility of PHP's array type makes it
> really hard to pin down whether a given object is "array-like" or not, and
> which attributes a particular function actually cares about.

What else besides array access, counting and traversing is possible that
may differ from classes that implement those interfaces?

> A general "intersection type" system might be more useful, because then you
> could require the parts you specifically needed, such as
> "traversable" or "traversable".

I think that's too complicated and we should make it as easy as possible
for PHP developers.

Also, there's already an RFC for intersection types but it was never
adopted: https://wiki.php.net/rfc/intersection_types

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Re: [RFC] "arrayable" pseudo type hint

2020-02-04 Thread Rowan Tommins
On Tue, 4 Feb 2020 at 18:06, Aimeos | Norbert Sendetzky 
wrote:

> Am 04.02.20 um 18:18 schrieb Larry Garfield:
> > The more I think on it, the less I like `arrayable`.  PHP arrays are
> > a terrible data structure from a type system point of view, with too
> > much functionality crammed into one variable type.
>
> The array internals are outside the scope of this proposal and are not
> affected in any way by this proposal.
>


I think Larry's point was that the flexibility of PHP's array type makes it
really hard to pin down whether a given object is "array-like" or not, and
which attributes a particular function actually cares about.

A general "intersection type" system might be more useful, because then you
could require the parts you specifically needed, such as
"traversable" or "traversable".

Regards,
-- 
Rowan Tommins
[IMSoP]


Re: [PHP-DEV] Re: [RFC] "arrayable" pseudo type hint

2020-02-04 Thread Aimeos | Norbert Sendetzky
Am 04.02.20 um 18:18 schrieb Larry Garfield:
>> interface Arrayable extends ArrayAccess, Countable, Traversable
>> {
>> public function toArray() : array;
>> }
>>
>> Then, methods signatures can support array and Array-like objects:
>>
>> function useArrayable( array|Arrayable $arg ) : array|Arrayable {
>> $cnt = count( $arg );
>> $value = $arg['key'];
>> foreach( $arg as $key => $entry );
>> is_object( $arg ) { $nativeArray = $arg->toArray(); }
>> return $arg;
>> }
>> 
>> If union data types are available and "iterable" is implemented as 
>> alias, an alias "arrayable" for "array|Arrayable" may be added as
>> well.
> 
> The more I think on it, the less I like `arrayable`.  PHP arrays are
> a terrible data structure from a type system point of view, with too
> much functionality crammed into one variable type.

The array internals are outside the scope of this proposal and are not
affected in any way by this proposal.

> If you want an object that shoves all the various bits of arrayness
> into one object, there's already ArrayObject, which you can extend if
> desired.

Tried that already, but other core developers made very clear that
ArrayObject is one of the worst implementations in PHP and that it's not
going to be improved or touched in any way and using it is highly
discouraged.

> Especially with union types, amalgam built in types like this are
> even less needed.

If an "arrayable" pseudo type should be implemented is subject to
discussion. It would be a short form for "array|Arrayable" (native type
or interface for array like objects) only offering a syntactical sugar
for developers.

> Aside from iterable, the only other built-in alias I would see is one
> for array|ArrayAccess.  But... it's now possible to do exactly like
> that, so I don't know how useful it would be.

"array|ArrayAccess" is not sufficient because arrays are also countable
and traversable and this isn't possible with union data types:

interface Arrayable extends ArrayAccess, Countable, Traversable

function useArrayable( array|Arrayable $arg ) {
$cnt = count( $arg );
$value = $arg['key'];
foreach( $arg as $key => $entry );
}

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Re: [RFC] "arrayable" pseudo type hint

2020-02-04 Thread Larry Garfield
On Tue, Feb 4, 2020, at 6:48 AM, Aimeos | Norbert Sendetzky wrote:
> I would like to modify my initial concept of an "arrayable" type because
> PHP core developers seems to be in favor of the upcoming union data
> types instead of adding a new "arrayable" pseudo type similar to "iterable".
> 
> So, I would like to propose an "Arrayable" interface that combines
> ArrayAccess, Countable and Traversable interfaces and adds a toArray()
> method:
> 
> interface Arrayable extends ArrayAccess, Countable, Traversable
> {
> public function toArray() : array;
> }
> 
> Then, methods signatures can support array and Array-like objects:
> 
> function useArrayable( array|Arrayable $arg ) : array|Arrayable {
> $cnt = count( $arg );
> $value = $arg['key'];
> foreach( $arg as $key => $entry );
> is_object( $arg ) { $nativeArray = $arg->toArray(); }
> return $arg;
> }
> 
> Adding a toArray() method also avoids controversy around using a magic
> __toArray() method, even if this would be easier for developers in this
> case.
> 
> If union data types are available and "iterable" is implemented as
> alias, an alias "arrayable" for "array|Arrayable" may be added as well.

The more I think on it, the less I like `arrayable`.  PHP arrays are a terrible 
data structure from a type system point of view, with too much functionality 
crammed into one variable type.

If you want an object that shoves all the various bits of arrayness into one 
object, there's already ArrayObject, which you can extend if desired.

Especially with union types, amalgam built in types like this are even less 
needed.

Aside from iterable, the only other built-in alias I would see is one for 
array|ArrayAccess.  But... it's now possible to do exactly like that, so I 
don't know how useful it would be.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-DEV] Re: [RFC] "arrayable" pseudo type hint

2020-02-04 Thread Aimeos | Norbert Sendetzky
I would like to modify my initial concept of an "arrayable" type because
PHP core developers seems to be in favor of the upcoming union data
types instead of adding a new "arrayable" pseudo type similar to "iterable".

So, I would like to propose an "Arrayable" interface that combines
ArrayAccess, Countable and Traversable interfaces and adds a toArray()
method:

interface Arrayable extends ArrayAccess, Countable, Traversable
{
public function toArray() : array;
}

Then, methods signatures can support array and Array-like objects:

function useArrayable( array|Arrayable $arg ) : array|Arrayable {
$cnt = count( $arg );
$value = $arg['key'];
foreach( $arg as $key => $entry );
is_object( $arg ) { $nativeArray = $arg->toArray(); }
return $arg;
}

Adding a toArray() method also avoids controversy around using a magic
__toArray() method, even if this would be easier for developers in this
case.

If union data types are available and "iterable" is implemented as
alias, an alias "arrayable" for "array|Arrayable" may be added as well.


Am 19.11.19 um 23:21 schrieb 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
> 
> 
> 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