On Thu, Jan 25, 2018 at 11:59 PM, Niklas Keller <m...@kelunik.com> wrote:
> Michael Morris <tendo...@gmail.com> schrieb am Fr., 26. Jan. 2018, 02:06: > >> On Thu, Jan 25, 2018 at 3:04 PM, Niklas Keller <m...@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 <le...@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 <le...@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.