Hi Andrea, After carefully reading the RFC again, and despite the fact that I globally agree, here are some suggestions and comments that were not discussed yet (sorry for this huge post) :
- The 'resource' hint does not exist 'as this would prevent moving from resources to objects for existing extensions, which some have already done (e.g. GMP)'. This is strange as moving an extension from resource to OO and keeping the same API is not common. Actually, such a move is quite useless if the API remains the same (it is just a little slower and, look, it's 'OO'). GMP is a very special case and, even in this case, PHP 7 could be the occasion to replace GMP functions with methods. Anyway, this special case does not justify, IMO, not to define a type hinting for resources (this would be the only undefined one). - I suggest you add a catch-all type ('mixed', for example), as this is very different from not setting the type, especially for static analysis. It would explicitly define that the element can be any type. - A 'null' type would be useful for return type. Once again, the reason is that a function returning 'null' is not the same as a function not defining its return type. This is DbC but, anyway, as soon as it checks the return type, your RFC has a foot in DbC. - More generally, beyond the proposed nullable hint (whose syntax is limited, ugly and not intuitive), what do you think of a multi-type syntax, something like a set of types, separated by '|' (like 'string|array'). Interesting for '|null' as this is the main use case, but '|bool' in return type is also a common use case to allow returning false, and many string functions would use (string|array). May I say that phpdoc already uses such a syntax without being shot down :) - Actually, I must admit that I have a problem with a syntax that does not fully support every usual cases. If a user wants to set explicit types in his code, in many case, it is just impossible. A simple example : even if I want to, I cannot write anything more precise than 'str_replace($search, $replace, $subject, int $count=null)', when I would like to write something like 'str_replace(string|array $search, string|array $replace...)'. And people reading my code, future compilers, and static analyzers would like me to write that too ! If we add a 'mixed' type, it is already better because explicit, but not precise enough for the tools that could use this information. And the case is very common. - How do you forbid arrays and resources weak conversion to scalar ? Do you modify the convert_to_xxx() functions or is it just specific to type hinting ? In this case, it means that internal and userspace functions won't follow the same weak rules (an int arg in an internal function will accept an array/resource/null zval while it will be refused for a userspace argument). There's an ambiguity here because, when you talk about 'the traditional weak type checking rules' followed by zend_parse_parameters(), that's not the 'weak type check' rules you define 10 lines above. - Another point is that modifying zend_parse_parameters() won't be sufficient to enforce strict checking (because too many internal functions get bare zvals and handle type checking and conversion by themselves). For all these reasons, I think we must extend the ARG_INFO mechanism to allow internal function developers to set type hinting in a similar way to userspace type hinting (just optimizing values for performance). The return type hint should be set there too. Anyway, if we want reflection to provide this information for internal functions, the only way is to add it to the ARG_INFO information (we could then provide a way to generate the function prototype from this info). That's a big work but I don't see another way to be consistent. - The following weak conversions : (bool -> float), (bool -> string), and (string -> bool) are not much more natural than (array -> scalar), or (resource -> int), which are forbidden. While it is natural in a C-like world to consider any non-null number as true, I don't see why we should allow sending a bool to a function expecting a float, even in weak mode. I would consider this as a bug, but there may be use cases I'm not aware of. Note that BC is not an argument here, as weak mode already modifies the way arguments are handled (by refusing arrays, resources, and null for scalars), so we are free to restrict it a little more if it makes sense. - I didn't see anything saying if you check the return type in weak mode. - Do you plan a way to define the return type of arguments passed by reference, or do you assume that input and output types must be the same ? Even if you assume they are the same, do you also check these types along with the function's return type ? What about a syntax like '<input-type>[:<output-type>]' (with an error if arg is not passed by ref) ? - In 'unaffected PHP functionality', you might change this : ' When the strict type-checking mode isn't in use (which is the default), function calls behave identically to previous PHP versions' as it is not exactly the case : setting a scalar type in front of an argument restricts the possible zval types he will accept. In one case, IS_ARRAY, IS_RESOURCE and IS_NULL inputs are converted, in the other, they are rejected when entering the function. So, you cannot say that weak type checking behaves exactly the same as PHP native type juggling. - Maybe a way to let the user decide whether he wants errors to be raised as exceptions or PHP errors (a declare addition/variation?). If we define such an option, it must go with the declare directive, not as an INI setting. Exception could contain the required and provided types. - Please, please, don't move declare() to '<?php strict' ! That's the most ambiguous syntax I can imagine. - About the 'numeric' type you would introduce in a future RFC, would you (in strict mode) allow everything accepted by is_numeric() or is it just a shortcut for 'int|float' ? Well, that's all for today. I spent 3 hours writing this from previous notes, but the subject deserves it. Of course, most of this is for a future RFC but we can start thinking about it. I send a copy of this post to Anthony because he probably has an interesting opinion on the subjects I'm listing here. Cheers, François -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php