Hi Zeev,

> -----Ursprüngliche Nachricht-----
> Von: Zeev Suraski [mailto:z...@zend.com]
> Gesendet: Samstag, 21. Februar 2015 18:22
> An: PHP internals
> Betreff: [PHP-DEV] Coercive Scalar Type Hints RFC
> 
> All,
> 
> 
> 
> I’ve been working with François and several other people from internals@ and 
> the PHP community to create a single-mode
> Scalar Type Hints proposal.
> 
> 
> 
> I think it’s the RFC is a bit premature and could benefit from a bit more 
> time, but given the time pressure, as well as the fact
> that a not fully compatible subset of that RFC was published and has people 
> already discussing it, it made the most sense to
> publish it sooner rather than later.
> 
> 
> 
> The RFC is available here:
> 
> 
> 
> wiki.php.net/rfc/coercive_sth
> 
> 
> 
> Comments welcome!
> 
> 
> Zeev

First of all, thank you and all others working on this RFC but also people 
working on another RFC related to scalar type hints. It is good that PHP will 
get scalar type hints eventually.

Although I think the strict mode as proposed in the v0.5 RFC is nice as such, I 
prefer this RFC simply by the fact that it does not introduce different modes. 
I genuinely believe that different modes will be very harmful for PHP.
Yet, this RFC is not perfect either. IMO PHP is not ready for scalar type 
hints, not for PHP 7.0 respectively and we should instead focusing on clearing 
the way for the introduction of scalar type hints in PHP 7.x and hence 
introduce all required BC breaks in PHP 7.0 which are necessary in order that 
scalar type hints can be added to PHP 7.x later on. 

I am provoking on purpose of course. But rightly so, because I think in all the 
debate about strict/weak scalar type hints we lost focus on what really matters 
in language growth, namely its maturation. 

For instance, Pierre and others carped about that string -> bool and float -> 
bool are accepted by this RFC. While I agree that it is a bad idea to apply 
implicit conversions to such input  (I would not even allow int -> bool to be 
honest), it makes totally sense for PHP to behave like this at the moment. I 
would even claim that null, array, object, literally everything should be 
accepted as well since the explicit (bool) accepts everything as well and some 
implicit castings such as the one in an if statement accepts also everything. 

>From questions like these:
> Boolean STH (bool):
> this is by far too weak. How strings could be consider as valid, how?
> "true" > Boolean true? I suppose then "false" will be boolean false?
> What's is the boolean value of float 0.5?
> At the very least only integer should be accepted, 0 > false, anything >=1 
> true

I get the impression that even internals start to get confused about the 
conversion rules PHP has. Implicitly convert something to bool should be 
exactly the same as an explicit conversion (thus straight forward to verify 
http://3v4l.org/nVgbG ).
We should start to eliminate the different behaviour of implicit/explicit 
castings [1], to have a consistent and predictable/obvious behaviour in the 
long run. Or in other words, and that is what I meant above, PHP's type system 
needs to mature. While I can understand that it looks beneficial to have all 
kind of reliefs for the beginner, it is rather harmful in the long run. PHP has 
so many inconsistencies and requires a user to be aware of all kind of edge 
cases that I think bugs are introduced more frequently than necessary. We 
already have different conversion mechanisms in PHP and I guess the reason why 
https://wiki.php.net/rfc/safe_cast was declined is based on the fact that most 
people did not want to see yet another group of conversion rules.

There were people claiming that PHP follows the philosophy that a user does not 
need to know anything about scalar types. PHP will deal with it via type 
juggling. A function/operator requires an int? Just pass a scalar and PHP will 
convert it automatically via type juggling to int. 
That is long gone (probably was never there) because the user had to know 
exactly what type can be passed or rather what values, otherwise bugs are 
inevitable. Consider the following:

 "a" % 1;
fmod("a", 0.5);

Kind of logical that % accepts any kind of scalar where fmod does not, right? I 
do not want to exaggerate too much on this but I think you get my position that 
PHP needs to get rid of this inconsistencies rather than adding yet another 
obstacle which impedes to reach consistency. Once scalar type hints are in 
place it should follow the conversion rules which we want to have in PHP in the 
long run otherwise the BC impact it would have to change them would be too big 
and we would at least need to wait till PHP 8 if not even PHP 9.

So what does that mean for scalar types?
IMO it means that way more important than adding scalar type hints to PHP 7.0 
is to agree on a new set of conversion rules for the long run. PHP should 
strive to have one consistent set of conversion rules which apply in all places 
where implicit or explicit conversion are used. Hence, the way (bool) works in 
the future needs to change as well [2]. That is my opinion. I am aware of that 
such a change would have a way to big BC break impact for PHP 7.0 (likewise the 
option 1 of this RFC). But can be introduced step by step [3] (kind of my 
choice of option) and migration tools could facilitate the migration to a new 
version. I think I am not alone with this opinion (I just read the email of 
Shashank) 

I see the migration plan roughly as follows:

PHP 7.0:
  - reserve keywords: bool, int, float including alternatives
  - deprecate alternative type names such as boolean, integer etc.

  - introduce new conversion functions which reflect the current behaviour of 
(bool), (int) etc.
      --> as mentioned above, they could be named oldSchoolBoolConversion etc. 
      --> Encourage users to use this function instead of (bool), (int) etc 
since (bool) etc. will change with PHP 8.0. Also mention, that this function 
should only be used if the weakness is really required otherwise use the new 
conversion functions from below

  - introduce new conversion functions which reflect the new defined conversion 
rule set (which shall be the only one encouraged in the future) Those functions 
shall trigger an E_RECOVERABLE_ERROR 
    --> encourage users to use this functions instead of (bool), (int) and 
oldSchoolBoolConversion etc.  (unless the weakness is really required, then use 
oldSchoolBoolConversion)

  - update the docs in order to reflect the new encouraged way. Also mention 
that:
     - (bool), (int) etc. will change their behaviour in PHP 8.0
     - internal functions will use the new conversion rules if not already done 
this way in PHP 8.0 (for instance, strstr will no longer accept a scalar as 
third parameter in the case where we do not support implicit casts to bool)  
     - operators will use the new conversion rules if not already done this way 
in PHP 8.0
     - (control structures will use the new conversion rules if not already 
done this way in PHP 8.0) =>Maybe this is too strict for most of you and goes 
against the spirit of PHP (I suppose some of you will say that - fair enough, I 
guess you are right). In this case, I would at least use the term "loose 
comparison" as mentioned here: 
http://php.net/manual/en/types.comparisons.php#types.comparisions-loose instead 
of using the term "conversion", then it is compatible with the changes 
introduced in PHP 8.0

PHP 7.1: necessary bug-fixes introduced with PHP 7.0
PHP 7.x: deprecate even more if required
PHP 8: 
  - introduce scalar type hints which reflect the conversion rules as defined 
(adding strict type hints as well is possible of course, whether with an 
ini-setting, a declare statement or individually with a modifier something like 
"strict int" for a single parameter or strict function for all parameters incl. 
return type or strict class for every type defined in the class is up to 
discussion)
  - exchange the behaviour of (bool), (int) etc. -> use the new conversion 
rules instead
  - change internal functions which do not yet obey to the new conversion rules
  - change the operators which do not yet obey to the new conversion rules (for 
instance, + would also emit an E_RECOVERABLE_ERROR for "a" + 1)
  - (change the control structures in order that they obey the new conversion 
rules as well) => as mentioned above, probably too strict for PHP

Back to this RFC.  think this RFC goes in the right direction with the 
specified conversion rules. Only thing to get rid of are the implicit 
conversions to bool from string, float and int IMO.
Moreover, I like that the RFC already has different steps for adding the new 
behaviour. Yet, I think it should slow down a little bit as shown. I think we 
need more time to come up with a very good strategic solution.

Thoughts?
 
Cheers,
Robert

[1] for instance, that implicit/explicit conversion behaves differently and 
that the implicit conversion in an if statement uses yet another behaviour. 
Operator signatures and function signatures behave differently, control 
structures and functions behave differently etc.

[2] (bool) would not longer accept all kind of input data - IMO it would not 
accept anything, PHP does not support conversions to bool. I would even change 
the way if works and disallow if(new Foo()){} for instance (since no conversion 
to bool exist anymore). PHP could add a function which behaves like the current 
(bool), maybe oldSchoolBoolConversion (ugly name in order that no one is 
encouraged to use it) and users would need to write 
if(oldSchoolBoolConversion(new Foo())){} to get the same behaviour as today. 




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

Reply via email to