strict_types will be default at some moment?

php.internals

David Rodrigues

5 years ago
Hello! I have been asked by a friend if declare(strict_types=1) will be applied by default for some version of PHP, like 9.x or will it be always required by all scripts forever. Someone can tell me? If yes, what is the reason for requiring it? Why it can't be the default behavior (or maybe, the unique behavior). Atenciosamente, David Rodrigues

Claude Pache

5 years ago
> Le 11 nov. 2020 à 21:20, David Rodrigues <david.proweb@gmail.com> a écrit : > > Why it can't be the default > behavior (or maybe, the unique behavior).
IMNSHO, a good reason for keeping weak typing, is that developers are not willing to review and refactor megabytes of valid code that take advantage of implicit type conversion. —Claude

Rowan Collins

5 years ago
On 11/11/2020 20:20, David Rodrigues wrote:
> I have been asked by a friend if declare(strict_types=1) will be applied by > default for some version of PHP, like 9.x or will it be always required by > all scripts forever. Someone can tell me? > > If yes, what is the reason for requiring it? Why it can't be the default > behavior (or maybe, the unique behavior).
The question (which I hear often) misunderstands the original intent of the declaration, as I understand it: the strict_types switch was not designed as a transition mechanism for old code, it was designed as a genuine choice between two different options, both equally new. Before PHP 7.0, there was no ability for a (user-defined) function to declare that it wanted an int, string, float, or boolean argument. When it was proposed that these "scalar type hints" be added, there were different, strongly held, opinions on how that should work, leading to at least 5 separate RFCs, several thousand mailing list posts, and a lot of general unhappiness. The idea behind the strict_types directive was to combine two versions of the feature into one system, allowing users to switch between them at will. The proposal made clear that both modes have their advantages and disadvantages. A few of those were affected by compatibility with older code - in particular, around the behaviour of built-in functions - but those were not the main driving factors behind providing two modes. Perhaps, 5 or 6 years on, things have changed. Certainly, there are a vocal community of users who see "strict_types=1" as unreservedly "better" in some fundamental way - but then, there always were, that's why the debate was so heated. I rather suspect that most of the arguments put forward for one position or the other then are just as true now. I do wonder if people would even be asking the question, if the modes had been named something like "scalar_types=coerce" and "scalar_types=error", and somehow arranged such that neither was in force by default. [PS: What a beautifully timed e-mail - "11/11/2020 20:20 UTC"!] Regards,
-- Rowan Tommins (né Collins) [IMSoP]

Girgias

5 years ago
On Wed, 11 Nov 2020 at 21:47, Rowan Tommins <rowan.collins@gmail.com> wrote:
> On 11/11/2020 20:20, David Rodrigues wrote: > > I have been asked by a friend if declare(strict_types=1) will be applied > by > > default for some version of PHP, like 9.x or will it be always required > by > > all scripts forever. Someone can tell me? > > > > If yes, what is the reason for requiring it? Why it can't be the default > > behavior (or maybe, the unique behavior). > > > The question (which I hear often) misunderstands the original intent of > the declaration, as I understand it: the strict_types switch was not > designed as a transition mechanism for old code, it was designed as a > genuine choice between two different options, both equally new. > > Before PHP 7.0, there was no ability for a (user-defined) function to > declare that it wanted an int, string, float, or boolean argument. When > it was proposed that these "scalar type hints" be added, there were > different, strongly held, opinions on how that should work, leading to > at least 5 separate RFCs, several thousand mailing list posts, and a lot > of general unhappiness. > > The idea behind the strict_types directive was to combine two versions > of the feature into one system, allowing users to switch between them at > will. The proposal made clear that both modes have their advantages and > disadvantages. A few of those were affected by compatibility with older > code - in particular, around the behaviour of built-in functions - but > those were not the main driving factors behind providing two modes. > > Perhaps, 5 or 6 years on, things have changed. Certainly, there are a > vocal community of users who see "strict_types=1" as unreservedly > "better" in some fundamental way - but then, there always were, that's > why the debate was so heated. I rather suspect that most of the > arguments put forward for one position or the other then are just as > true now. > > I do wonder if people would even be asking the question, if the modes > had been named something like "scalar_types=coerce" and > "scalar_types=error", and somehow arranged such that neither was in > force by default. > > > [PS: What a beautifully timed e-mail - "11/11/2020 20:20 UTC"!] > > > Regards, > > -- > Rowan Tommins (né Collins) > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
As Rowan pointed out strict_types have a complicated history, and to some extent were a bandage fix, a very good one which might have been *too* good. Let me try to explain by looking at how strict_types circumvented some of the nonsensical coercive mode behaviour. (Reminding that this is in PHP 5 days) 1. Preventing float to integer conversion, which could lead to a loss of data if a fractional part exists 2. Preventing integers, floats, and strings to pass a boolean type declaration 3. Preventing booleans to pass an integer, float, or string type declaration 4. Preventing internal functions from coercing null to the corresponding scalar type 5. Preventing strings which look numeric (i.e. leading-numeric strings) to pass integer/float checks It should be noted that all of these issues exist (in "weak" typing mode) in PHP 7 and only the last item of the previous list has been "fixed" in PHP 8.0, with the "Stricter Numeric Strings" RFC. [1] The "competing" RFC to strict_type scalar type declarations "Coercive Types for Function Arguments" [2] made provisions to some of these cases, namely 1, 3, and 5. However, they were made as deprecation notices, which until PHP 8.0, were silenced by default. Case 4 might finally be solved as in PHP 8.0 a lot of work went towards making internal functions accept null (or have a reasonable default value) for optional arguments. For case 2 one can argue both ways that it makes sense that non boolean values resolve to true or false to pass a type declaration. Now going back to strict_types being *too* good of a bandage fix is that none of the above issues have been addressed during the PHP 7 release cycle which could have made coercive typing less surprising (the float to integer being the most surprising IMHO) by introducing warnings/deprecation notices and making them TypeErrors in PHP 8. As such I think, it would be better to improve coercive typing during this major release cycle by making it stricter and more akin to strict_type semantics such that the strict_type declare statement might become "obsolete" in PHP 9. Best regards, George P. Banyard [1] https://wiki.php.net/rfc/saner-numeric-strings [2] https://wiki.php.net/rfc/coercive_sth

Mark Randall

5 years ago
On 11/11/2020 20:20, David Rodrigues wrote:
> If yes, what is the reason for requiring it? Why it can't be the default > behavior (or maybe, the unique behavior).
There was some discussion around the idea of adding language editions to PHP for 8.0, however the pandemic resulted in to the in-person conference that would have discussed it being cancelled. If that ever goes back into discussion, I think that I and many others would argue that strict_types=1 would be a baseline requirement of the first edition.