Re: [RFC][DISCUSSION] Collection Inspection
| From: | Michael Morris | Date: | Fri, 26 Jan 2018 14:20:31 +0000 |
| Subject: | Re: [RFC][DISCUSSION] Collection Inspection | ||
| References: | 1 2 3 4 5 6 7 8 9 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-101694@lists.php.net to get a copy of this message | ||
On Thu, Jan 25, 2018 at 11:59 PM, Niklas Keller <me@kelunik.com> wrote:
> Michael Morris <tendoaki@gmail.com> schrieb am Fr., 26. Jan. 2018, 02:06:
>
>> On Thu, Jan 25, 2018 at 3:04 PM, Niklas Keller <me@kelunik.com> wrote:
>>
>> >
>> >>
>> >> $a instanceof array<string>
>> >>
>> >
>> > That might work, but array<string> should only return true if it's an
>> > array, not for anything that implements ArrayAccess.
>> >
>> >
>>
>> Related:
>>
>> On Thu, Jan 25, 2018 at 4:11 PM, Levi Morrison <levim@php.net> wrote:
>>
>> >
>> >
>> > I see no value to this operator being applied to non-array
>> > traversables.
>>
>>
>> If an array access object can't masquerade as an array it loses some of
>> its
>> value, but Niklas is right - it is important to distinguish such objects
>> from native arrays. One solution would be to promote "iterable" to
>> keyword
>> status. The flexibility to take any iterable will be needed I think.
>>
>> $a instanceof iterable<string>
>>
>> Would return true for anything iterable (which we can already test with
>> is_iterable() ) where all values where strings.
>>
>> On Thu, Jan 25, 2018 at 4:11 PM, Levi Morrison <levim@php.net> wrote:
>> >
>> > Our iterators cannot always be reliably rewound, such as
>> > when using generators. Checking that the generator returns only
>> > strings would consume all the input and would therefore be useless.
>>
>>
>> True - I hadn't thought of those. But as of PHP 7 generators can type
>> declare their return value.
>
>
> They can only define generator as return type, which is what they return
> when you call a generator function.
>
> Even if you could declare the return type of the generator, you'd still
> have the same problem with the yielded values.
>
See my comment about coding around morons being a pointless exercise. You
throw an error and force the moron to fix their code.
>
> So, given
$a instanceof iterable<string>, if
>> $a is a reference to a generator, then the engine could check the return
>> type declaration and only give true on a match without attempting to use
>> the generator.
>>
>> We can follow this pattern farther - The return of an
>> ArrayAccess::offsetGet and Iterator::current() can be similarly tested by
>> instanceof rather than actually pulling data from these methods.
>>
>> We are having the return rely on the promise of the code, but in each case
>> TypeError would be raised anyway if it breaks it's promise to instanceof
>> so
>> errors aren't being avoided.
>>
>>
>>
>> > Returns true if $a is an array (or implements array access) and that all
>> >> it's members are strings.
>> >>
>> >> $b instanceof SomeClass<string>
>> >>
>> >> Returns true if SomeClass can be iterated and contains only strings.
>> >>
>> >
>> > This would block generics with that syntax then.
>> >
>>
>> I don't understand this comment.
>>
>
> You restrict these type parameters to iterators, but generics are useful
> in a lot more places.
>
iterABLE --- not iterOR. Two different things.
Iterable is a psuedotype in PHP covering anything that can be traversed
with foreach, including std_class, which is what I think what you mean by
generator. There's even an existing function, is_iterable() to detect
them. $a instanceof iterable will return the same as is_iterable($a);
Generics specifically are already detectable by $a instanceof stdClass
$a instanceof Iterator detected that interface, but not arrays and
generics.
$a instanceof iterable would detect all three.
The similarity of the names is regrettable, but it's already in place and
can't be changed at this point.