-
Notifications
You must be signed in to change notification settings - Fork 8k
Iterable pseudo-type #1941
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Iterable pseudo-type #1941
Conversation
|
@mokeev1995 PHP cannot iterate strings by characters anyway (only by bytes which makes little sence with multibyte encodings). And you cannot pass a sting to |
|
Strings cannot become |
|
ok, thanks) |
|
I'm afraid this would be a serious BC break in minor version. It would be perfectly fine for 7.0 (at least as part of reserved types RFC), but since it's already out, the only reasonable version to target is 8.0. |
|
@Majkl578 From the first page of your first link, there are 10 entries. 8 have extra words (e.g. class IterableFilterIterator) and so wouldn't be affected. 1 of the others is in a namespace and so wouldn't be affected. Which leaves 1 example.
Most people don't consider adding new classes to be a BC break. It's only changing behaviour of existing classes/functions, or removing stuff that is a 'real' BC break. |
Which is still more than 0. And we are not even considering all the private code out there.
Not true, real-world applications typically import classes with
This proposal is not to add new class, but a pseudotype that would break all code using typehint for interface/class named |
|
@Majkl578 Behavioral changes are considered serious BC breaks, while this would only cause a BC break due to naming, which can easily be fixed with simple find-and-replace. Yes, it is technically a BC break, but one that can be fixed in a matter of minutes without actually examining any code. |
|
|
||
| if (arg_info->class_name && zend_string_equals_literal_ci(arg_info->class_name, "Traversable")) { | ||
| return 1; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need these special compatibility rules? why not just check for IS_ITERABLE?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allows a degree of co/contravariance in extending/implementing classes. Parameter types of array or Traversable can be broadened to iterable or return types declaring iterable can be restricted to either array or Traversable.
|
It would be pretty cool if, somehow (I have no idea if this is possible), after this pseudo type has been added, we could start using the array_* functions indiscriminately across all the iterable types. |
This PR was merged into the 1.12 branch. Discussion ---------- PhpdocTypesFixer - support iterable type PHP 7.1 will have the `iterable` type. We should treat it like the other types we normalize. Refs: * https://wiki.php.net/rfc/iterable * php/php-src#1941 * https://github.com/php/php-src/blob/php-7.1.0RC2/UPGRADING#L25-L27 Commits ------- 0d8da6e Added support for the new iterable type
It is common for a function to accept or return either an
arrayor an object implementingTraversableto be used withforeach. However, becausearrayis a primitive type andTraversableis an interface, there currently is no way to use a type declaration on a parameter or return type to indicate that the value is iterable.This PR proposes a new
iterablepseduo-type. This type is analogous tocallable, accepting multiple types instead of one single type.iterableaccepts anyarrayor object implementingTraversable. Both of these types are iterable usingforeachand can be used withyield fromwithin a generator.iterablecan be used as a parameter type to indicate that a function requires a set of values, but does not care about the form of the value set (array,Iterator,Generator, etc.) since it will be used withforeach. If a value is not an array or instance ofTraversable, aTypeErrorwill be thrown.iterablecan also be used as a return type to indicate a function will return an iterable value. If the returned value is not an array or instance ofTraversable, aTypeErrorwill be thrown.Parameters declared as
iterablemay usenullor an array as a default value.Functions declaring
iterableas a return type may also be generators.This proposal also adds a function
is_iterable()that returns a boolean:trueif a value is iterable and will be accepted by theiterablepseudo-type,falsefor other values.RFC: https://wiki.php.net/rfc/iterable