[PHP-DEV] Renaming "strict types" to "scalar type coercion"

Hello internals,

Many, many people start their files fairly religiously:

<?php declare(strict_types=1);

and I say "religiously" because from talking to people in real life,
reddit, workplaces, etc, very few php programmers actually know what
this does but do it nonetheless. I've heard everything from "it
enables type hints" to "it makes it so that I know I got my class
instead of an int" to getting it right, but thinking it applies to
code calling from another file, and not them calling code.

Granted, I haven't done a scientific poll (though I did one on Reddit
this morning for giggles to ensure it isn't just the people I know).

One thing is clear is that "strict types" may be a bit of poor word
choice and gives people a false sense of security that it is "safe" or
"more correct" when this obviously isn't true. Thus, I'd like to
propose, for PHP 9, simply renaming it from strict_types to
scalar_type_coercion and flipping the value:

<?php declare(strict_types=1);

to

<?php declare(scalar_type_coercion=0);

Perhaps it might even be worth adding a secondary vote to flip the
default, such that if you want to "old" behavior back:

<?php declare(scalar_type_coercion=1);

I'm not attached to the name "scalar_type_coercion" by any stretch,
but I do feel that "strict_types" gives people the wrong idea about
what is going on when they enable it and renaming it to something more
clear might be helpful.

What are your thoughts?

PS. Personally, I would rather unify non-strict and strict in some way
that makes sense ... so, that route sounds nice too.

Robert Landers
Software Engineer
Utrecht NL

Hi,

One thing is clear is that "strict types" may be a bit of poor word
choice and gives people a false sense of security that it is "safe" or
"more correct" when this obviously isn't true. Thus, I'd like to
propose, for PHP 9, simply renaming it from strict_types to
scalar_type_coercion and flipping the value:

<?php declare(strict_types=1);

to

<?php declare(scalar_type_coercion=0);

This not better. Even with `declare(scalar_type_coercion=0)`, there will be scalar type conversions between string and int/float when you add numeric strings or when you concatenate a string with an int.

IMO, the real problem with the current name, is that there is no clue that this directive is specifically about arguments and return values in function/method calls.

Perhaps it might even be worth adding a secondary vote to flip the
default, such that if you want to "old" behavior back:

<?php declare(scalar_type_coercion=1);

That would force to edit thousands of files, ... for exactly zero gain. Have you heard about the Red Queen's race?

Moreover, there are many places where it is not possible to add such a declaration. For instance, `array_map(...)`, etc., always use `strict_types=0` when invoking the callback. Changing that would also be a big BC break.

—Claude

On 18/06/2024 17:37, Robert Landers wrote:

One thing is clear is that "strict types" may be a bit of poor word
choice and gives people a false sense of security that it is "safe" or
"more correct" when this obviously isn't true.

I totally agree with this sentiment. I don't think it should be called "strict", and I don't think it should be "on or off" either.

If I had a time machine, I'd propose something like:

declare(scalar_args=coerce);
declare(scalar_args=error);

Or perhaps:

declare(coerce_scalar_args=if_safe);
declare(coerce_scalar_args=never);

But...

Thus, I'd like to propose, for PHP 9, simply renaming it...

I'm not sure the pain is worth it. We'd have to introduce support gradually, probably not phasing out the old name until 10.0 at the earliest, so you'd just end up with more confusion with people not understanding if they were the same thing, which one to use in which version, etc.

Perhaps it might even be worth adding a secondary vote to flip the
default, such that if you want to "old" behavior back

You're falling into the same trap you're describing: assuming that strict_types=0 is an "older" mode, or a "worse" one. Both modes were introduced at exactly the same time, as a direct choice to users between two different styles, which had been proposed in competing RFCs.

Changing the default, and the name, but keeping the same behaviour, would just be a huge mess.

Personally, I would rather unify non-strict and strict in some way that makes sense

I think this is where we should be focussing our attention. We've had some great RFCs over the last few years tightening up some of the weirder excesses of PHP's type juggling system.

With a tight enough definition of "numeric string" and other coercible values, I think "mode 0" could be strict enough that "mode 1" wouldn't feel so necessary.

Then again, I was broadly in favour of the original coercive-only proposal for scalar type parameters, and there are those who felt strongly on the other side. The debate was extremely heated, and I'm not in a hurry to reopen it.

Regards,

--
Rowan Tommins
[IMSoP]

On Tue, 18 Jun 2024, 17:40 Robert Landers, <landers.robert@gmail.com> wrote:

Hello internals,

Many, many people start their files fairly religiously:

<?php declare(strict_types=1); and I say "religiously" because from talking to people in real life, reddit, workplaces, etc, very few php programmers actually know what this does but do it nonetheless.

I think there’s almost certainly a degree of truth, not just in PHP but programming in general, in the idea that there are many people who will blindly follow a convention for no better reason they once heard someone they considered more senior than themselves say the words “best practice”

But I don’t think the meaning of strict_types in PHP is unclear. It’s right there in the manual https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.strict

If anyone is daft enough to use a language feature without referencing what it means or what it does, let them clean up any problems which arise for them as a result.

If I were to support any change to how this feature works for PHP 9, I think it would be providing a mechanism to enable it for all files at once, maybe either via a .ini setting such as strict_types_default=1 or a new declare which applies to all files included or autoloaded from that point on, i.e. a declare that could be used as the first line of an entrypoint script to make all files in a project have strict typing mode enabled/disabled (unless a particular file overrides for its own scope with its own declare).

Changing the name to anything other than what it is now, with or without flipping the value, just seems like a major BC headache for no gain.

-Dave

On Wed, 19 Jun 2024, 09:31 Robert Landers, <landers.robert@gmail.com> wrote:

The problem isn’t so much this, but in that it has become a dogma to
“have working types” and trying to explain why they do or do not
need/want it in the current context becomes a hopeless argument
because you are attacking their world-view instead of having an
academic argument

If the feature was an RFC being introduced today and you were suggesting using a better, more descriptive name than strict_types I’d agree.

But it is what it is, it’s already in the language, it’s already very widely used and changing the name now won’t solve any problem, to whatever extent that problem exists (which I honestly don’t think is very big), of there being a cohort of users who rigidly stick to using this declare because they’ve been told they should always do so, or because they have a dogmatic opinion about how PHP’s type system should work in their ideal of the language.

Both those groups would continue to use the directive everywhere, regardless of what it was called. And it’s their code, their right. No one is under any obligation to engage in an academic argument to justify design decisions in code they own.

-Dave

On Tue, Jun 18, 2024 at 9:18 PM Claude Pache <claude.pache@gmail.com> wrote:

Hi,

> One thing is clear is that "strict types" may be a bit of poor word
> choice and gives people a false sense of security that it is "safe" or
> "more correct" when this obviously isn't true. Thus, I'd like to
> propose, for PHP 9, simply renaming it from strict_types to
> scalar_type_coercion and flipping the value:
>
> <?php declare(strict_types=1);
>
> to
>
> <?php declare(scalar_type_coercion=0);

This not better. Even with `declare(scalar_type_coercion=0)`, there will be scalar type conversions between string and int/float when you add numeric strings or when you concatenate a string with an int.

This is a really good point and worth thinking about. I kinda like
Rowan's suggestion of scalar_args with a usage of string values
instead of integers.

IMO, the real problem with the current name, is that there is no clue that this directive is specifically about arguments and return values in function/method calls.

Yes. This is kinda what I was hoping to address, but like you said,
the name I suggested didn't really capture the semantics either. :smiley:

> Perhaps it might even be worth adding a secondary vote to flip the
> default, such that if you want to "old" behavior back:
>
> <?php declare(scalar_type_coercion=1);

That would force to edit thousands of files, ... for exactly zero gain. Have you heard about the Red Queen's race?

This is a pretty simple search-and-replace, so I don't think it would
be hard to update. That being said, there still needs to be a
deprecation strategy that makes sense. As to it being "zero gain,"
words have meaning and choosing the right ones (even if it is years
later) can sometimes be completely worth it and even have monetary
gains.

Moreover, there are many places where it is not possible to add such a declaration. For instance, `array_map(...)`, etc., always use `strict_types=0` when invoking the callback. Changing that would also be a big BC break.

—Claude

Robert Landers
Software Engineer
Utrecht NL

On Tue, Jun 18, 2024 at 10:46 PM Rowan Tommins [IMSoP]
<imsop.php@rwec.co.uk> wrote:

On 18/06/2024 17:37, Robert Landers wrote:

One thing is clear is that "strict types" may be a bit of poor word
choice and gives people a false sense of security that it is "safe" or
"more correct" when this obviously isn't true.

I totally agree with this sentiment. I don't think it should be called "strict", and I don't think it should be "on or off" either.

If I had a time machine, I'd propose something like:

declare(scalar_args=coerce);
declare(scalar_args=error);

Or perhaps:

declare(coerce_scalar_args=if_safe);
declare(coerce_scalar_args=never);

This is nice. I like it :slight_smile:

But...

Thus, I'd like to propose, for PHP 9, simply renaming it...

I'm not sure the pain is worth it. We'd have to introduce support gradually, probably not phasing out the old name until 10.0 at the earliest, so you'd just end up with more confusion with people not understanding if they were the same thing, which one to use in which version, etc.

I honestly don't know how the deprecation would work, or what makes
sense. Supporting both makes sense and as long as the behavior stays
exactly the same, and they are both set to the same thing, that would
probably be fine for awhile. Is it confusing... I wouldn't find it
confusing unless I was working on something that supported <9 and >9
and eventually 8.x will EoL and then it won't be so confusing anymore.

Perhaps it might even be worth adding a secondary vote to flip the
default, such that if you want to "old" behavior back

You're falling into the same trap you're describing: assuming that strict_types=0 is an "older" mode, or a "worse" one. Both modes were introduced at exactly the same time, as a direct choice to users between two different styles, which had been proposed in competing RFCs.

Changing the default, and the name, but keeping the same behaviour, would just be a huge mess.

Personally, I would rather unify non-strict and strict in some way that makes sense

I think this is where we should be focussing our attention. We've had some great RFCs over the last few years tightening up some of the weirder excesses of PHP's type juggling system.

I've been mulling this around in my head last night and this morning.
I think I have something that makes sense, based mostly on information
loss. Essentially, an int could become a float (within some limits),
but a float can only become an int if it is an int itself. The same
concept of a string, where "123test" couldn't become a number because
"test" would be lost. Booleans are tricky, but I'd be inclined to keep
it as-is; otherwise, the BC break would be unbearable.

I think something like that would logically make sense. Whether or not
it would be feasible to implement in a performant way, I have no idea
(but it would be nice to clean up that area of the C code since it's a
bit of a tangle, IMHO). Interestingly, we could still do normal
coercion but just warn when there is information loss. Then, people
can ignore/catch those warnings and do whatever they want with them.
If information loss is what you want and you want to get rid of the
warning, you can simply add an explicit cast, but it would be nice
also to adjust casting so you can do

(int|null) $value; // or (?int) $value

so null won't be cast to zero. But that should probably be a totally
separate RFC and out of scope atm.

With a tight enough definition of "numeric string" and other coercible values, I think "mode 0" could be strict enough that "mode 1" wouldn't feel so necessary.

Then again, I was broadly in favour of the original coercive-only proposal for scalar type parameters, and there are those who felt strongly on the other side. The debate was extremely heated, and I'm not in a hurry to reopen it.

Regards,

--
Rowan Tommins
[IMSoP]

Robert Landers
Software Engineer
Utrecht NL

On Tue, Jun 18, 2024 at 11:04 PM David Gebler <davidgebler@gmail.com> wrote:

On Tue, 18 Jun 2024, 17:40 Robert Landers, <landers.robert@gmail.com> wrote:

Hello internals,

Many, many people start their files fairly religiously:

<?php declare(strict_types=1);

and I say "religiously" because from talking to people in real life,
reddit, workplaces, etc, very few php programmers actually know what
this does but do it nonetheless.

I think there's almost certainly a degree of truth, not just in PHP but programming in general, in the idea that there are many people who will blindly follow a convention for no better reason they once heard someone they considered more senior than themselves say the words "best practice"

But I don't think the meaning of strict_types in PHP is unclear. It's right there in the manual PHP: Type declarations - Manual

If anyone is daft enough to use a language feature without referencing what it means or what it does, let them clean up any problems which arise for them as a result.

The problem isn't so much this, but in that it has become a dogma to
"have working types" and trying to explain why they do or do not
need/want it in the current context becomes a hopeless argument
because you are attacking their world-view instead of having an
academic argument.

If I were to support any change to how this feature works for PHP 9, I think it would be providing a mechanism to enable it for all files at once, maybe either via a .ini setting such as strict_types_default=1 or a new declare which applies to all files included or autoloaded from that point on, i.e. a declare that could be used as the first line of an entrypoint script to make all files in a project have strict typing mode enabled/disabled (unless a particular file overrides for its own scope with its own declare).

I've explicitly written code without strict types because, in that
context, I want coercion (mostly when dealing with env vars)
surrounded by files with strict types enabled. Multiple steps would
have to be taken to make this possible (i.e., requiring the setting on
every file, whether off or on), negating the entire feature of having
it set globally. There may be a path where this makes sense, but I
don't think we can get there from here.

Changing the name to anything other than what it is now, with or without flipping the value, just seems like a major BC headache for no gain.

-Dave

Robert Landers
Software Engineer
Utrecht NL

Hi David, Robert,

wt., 18 cze 2024 o 23:12 David Gebler <davidgebler@gmail.com> napisał(a):

If I were to support any change to how this feature works for PHP 9, I think it would be providing a mechanism to enable it for all files at once, maybe either via a .ini setting such as strict_types_default=1 or a new declare which applies to all files included or autoloaded from that point on, i.e. a declare that could be used as the first line of an entrypoint script to make all files in a project have strict typing mode enabled/disabled (unless a particular file overrides for its own scope with its own declare).

Changing the name to anything other than what it is now, with or without flipping the value, just seems like a major BC headache for no gain.

I share a similar opinion here.
I’d also rather see a proposal that enables setting the declares outside of PHP files as this is mostly the same line for every file in most codebases I work with.

name it .phpdeclare in the execution directory or places where certain PHP files are read by the PHP interpreter, whatever

# Global default directives
[*.php]
strict_types = 1
ticks = 0
encoding = UTF-8

# Directives for specific directories
[src/*.php]
strict_types = 1

[tests/*.php]
strict_types = 0

# Directives for specific files
[scripts/setup.php]
strict_types = 1
ticks = 1

Just an example, shoving some declares can be set using glob-like patterns or specific files.
I see potential in this kind of declaring these directives for future extensions.
This is something I’d love to consider instead of just renaming things we already have.

Cheers,
Michał Marcin Brzuchalski

Am 19.06.2024 um 17:34 schrieb Larry Garfield:

Also, as someone who does put every file into strict mode as a matter of course, and appreciates the many languages that do not even have a concept of non-strict mode (like Go or Rust), I really don't appreciate the backhanded comments in this thread about people who, you know, care about type safety. (Something that weak mode, when it was introduced in PHP 7, only marginally provided if at all.) Strict mode prevents bugs, full stop, and we should not fault anyone for applying that bug-stopper tool liberally.

What Larry and Gina said.

On Jun 18, 2024, at 5:04 PM, David Gebler <davidgebler@gmail.com> wrote:

On Tue, 18 Jun 2024, 17:40 Robert Landers, <landers.robert@gmail.com> wrote:

Hello internals,

Many, many people start their files fairly religiously:

<?php declare(strict_types=1); and I say "religiously" because from talking to people in real life, reddit, workplaces, etc, very few php programmers actually know what this does but do it nonetheless.

I think there’s almost certainly a degree of truth, not just in PHP but programming in general, in the idea that there are many people who will blindly follow a convention for no better reason they once heard someone they considered more senior than themselves say the words “best practice”

There is a notable term for that: “Cargo Cult Programming”:

https://en.wikipedia.org/wiki/Cargo_cult_programming

#fwiw

-Mike

On Tuesday, 18 June 2024 at 17:37, Robert Landers <landers.robert@gmail.com> wrote:

Hello internals,

[...]

What are your thoughts?

As self-proclaimed leading expert on PHP type juggling.
That it is a terrible idea with no gains whatsoever.
Renaming the declare statement does not improve the situation.

PS. Personally, I would rather unify non-strict and strict in some way
that makes sense ... so, that route sounds nice too.

See my old meta RFC: GitHub - Girgias/unify-typing-modes-rfc: PHP RFC: Unify PHP's typing modes

It is a somewhat known hot take from mine that I think the strict_type declare statement was a mistake. [1]
Mainly because it affects barely nothing in regard to the engine.

I have written/co-authored multiple RFCs over the years to make the default coercion mode less whack. [2][3][4][5][6][7]
And my container/offset RFC is in the same vein [8] which lead me into a different rabbit hole then the one I was expecting to explore which is addressing PHP's weird comparison semantics. [9]

Therefore, I would rather we focus on *actually* fixing PHP's semantics, than arguing about changing the name of something that shouldn't really exist in the first place.

Best regards,

Gina P. Banyard

[1] Slide 68 of my PHP UK talk "PHP's Type System Dissected": https://gpb.moe/doc/slides/PHP_Type_System_Talk_PHPUK2023.pdf
[2] PHP: rfc:saner-numeric-strings
[3] PHP: rfc:implicit-float-int-deprecate
[4] PHP: rfc:saner-inc-dec-operators
[5] PHP: rfc:locale_independent_float_to_string
[6] PHP: rfc:exit-as-function
[7] PHP: rfc:deprecate-boolean-string-coercion
[8] php-rfcs/container-offset-behaviour.md at master · Girgias/php-rfcs · GitHub
[9] php-rfcs/comparison-equality-semantics.md at master · Girgias/php-rfcs · GitHub

On Wed, Jun 19, 2024, at 10:07 AM, Gina P. Banyard wrote:

On Tuesday, 18 June 2024 at 17:37, Robert Landers
<landers.robert@gmail.com> wrote:

Hello internals,

[...]

What are your thoughts?

As self-proclaimed leading expert on PHP type juggling.
That it is a terrible idea with no gains whatsoever.
Renaming the declare statement does not improve the situation.

PS. Personally, I would rather unify non-strict and strict in some way
that makes sense ... so, that route sounds nice too.

See my old meta RFC: GitHub - Girgias/unify-typing-modes-rfc: PHP RFC: Unify PHP's typing modes

It is a somewhat known hot take from mine that I think the strict_type
declare statement was a mistake. [1]
Mainly because it affects barely nothing in regard to the engine.

I have written/co-authored multiple RFCs over the years to make the
default coercion mode less whack. [2][3][4][5][6][7]
And my container/offset RFC is in the same vein [8] which lead me into
a different rabbit hole then the one I was expecting to explore which
is addressing PHP's weird comparison semantics. [9]

Therefore, I would rather we focus on *actually* fixing PHP's
semantics, than arguing about changing the name of something that
shouldn't really exist in the first place.

Best regards,

Gina P. Banyard

[1] Slide 68 of my PHP UK talk "PHP's Type System Dissected":
https://gpb.moe/doc/slides/PHP_Type_System_Talk_PHPUK2023.pdf
[2] PHP: rfc:saner-numeric-strings
[3] PHP: rfc:implicit-float-int-deprecate
[4] PHP: rfc:saner-inc-dec-operators
[5] PHP: rfc:locale_independent_float_to_string
[6] PHP: rfc:exit-as-function
[7] PHP: rfc:deprecate-boolean-string-coercion
[8]
php-rfcs/container-offset-behaviour.md at master · Girgias/php-rfcs · GitHub
[9]
php-rfcs/comparison-equality-semantics.md at master · Girgias/php-rfcs · GitHub

What Gina said. Renaming the declare key would involve changing *literally millions* of files, even if it's over the course of a decade, for little if any benefit.

Reducing the delta between weak mode and strict mode to the point that it makes little difference (by making the PHP type juggling system less nonsensical and random) is a much more achievable goal, and actually has value to justify the effort (both for Internals and for people updating their code).

Also, as someone who does put every file into strict mode as a matter of course, and appreciates the many languages that do not even have a concept of non-strict mode (like Go or Rust), I really don't appreciate the backhanded comments in this thread about people who, you know, care about type safety. (Something that weak mode, when it was introduced in PHP 7, only marginally provided if at all.) Strict mode prevents bugs, full stop, and we should not fault anyone for applying that bug-stopper tool liberally.

--Larry Garfield

On Wed, Jun 19, 2024 at 5:43 PM Sebastian Bergmann <sebastian@php.net> wrote:

Am 19.06.2024 um 17:34 schrieb Larry Garfield:
> Also, as someone who does put every file into strict mode as a matter of course, and appreciates the many languages that do not even have a concept of non-strict mode (like Go or Rust), I really don't appreciate the backhanded comments in this thread about people who, you know, care about type safety. (Something that weak mode, when it was introduced in PHP 7, only marginally provided if at all.) Strict mode prevents bugs, full stop, and we should not fault anyone for applying that bug-stopper tool liberally.

What Larry and Gina said.

Strange, I don't have an email from Larry! But I suspect it will show
up eventually... I look forward to it!

I'll go ahead and risk an out-of-context reply, but FWIW, it goes both
ways :slight_smile: People get irrational about this topic, either for-or-against.

In any case, there is not any "type safety" in PHP because PHP doesn't
know something is the wrong type until runtime. Further, it clearly
doesn't stop bugs, otherwise we'd all be out of a job by now.

Robert Landers
Software Engineer
Utrecht NL

On 19/06/2024 09:30, Robert Landers wrote:

Essentially, an int could become a float (within some limits),
but a float can only become an int if it is an int itself. The same
concept of a string, where "123test" couldn't become a number because
"test" would be lost.

Both of these are already covered, at least as far as parameter/return types, which is what "strict_types" controls...

'123test' is rejected, not coerced to int, as of 8.0: Online PHP editor | output for nvbML

Losing precision on a float-to-int is deprecated, so will presumably error as of 9.0: Online PHP editor | output for vvD2e

--
Rowan Tommins
[IMSoP]

From: Gina P. Banyard <internals@gpb.moe>
Sent: Wednesday, June 19, 2024 5:08 PM

On Tuesday, 18 June 2024 at 17:37, Robert Landers
<landers.robert@gmail.com> wrote:

> Hello internals,
>
> [...]
>
> What are your thoughts?

As self-proclaimed leading expert on PHP type juggling.
That it is a terrible idea with no gains whatsoever.
Renaming the declare statement does not improve the situation.

> PS. Personally, I would rather unify non-strict and strict in some way
> that makes sense ... so, that route sounds nice too.

See my old meta RFC: GitHub - Girgias/unify-typing-modes-rfc: PHP RFC: Unify PHP's typing modes

It is a somewhat known hot take from mine that I think the strict_type
declare statement was a mistake. [1]
Mainly because it affects barely nothing in regard to the engine.

I have written/co-authored multiple RFCs over the years to make the
default coercion mode less whack. [2][3][4][5][6][7]
And my container/offset RFC is in the same vein [8] which lead me into a
different rabbit hole then the one I was expecting to explore which is
addressing PHP's weird comparison semantics. [9]

Therefore, I would rather we focus on *actually* fixing PHP's semantics,
than arguing about changing the name of something that shouldn't really
exist in the first place.

Talking about 'going back in time' and sanitizing type coercion, I immediately had to think about the rejected 'Coercive Types for Function Arguments' RFC Zeev created as an alternative to the 'Scalar Type Declaration' RFC which was ultimately chosen and implemented.

https://wiki.php.net/rfc/coercive_sth

It seems that parts of what that RFC suggested have been implemented over time. In retrospect maybe this should have been the direction?

--
Vincent de Lau

[1] Slide 68 of my PHP UK talk "PHP's Type System Dissected":
https://gpb.moe/doc/slides/PHP_Type_System_Talk_PHPUK2023.pdf
[2] PHP: rfc:saner-numeric-strings
[3] PHP: rfc:implicit-float-int-deprecate
[4] PHP: rfc:saner-inc-dec-operators
[5] PHP: rfc:locale_independent_float_to_string
[6] PHP: rfc:exit-as-function
[7] PHP: rfc:deprecate-boolean-string-coercion
[8] https://github.com/Girgias/php-rfcs/blob/master/container-offset-
behaviour.md
[9] https://github.com/Girgias/php-rfcs/blob/master/comparison-equality-
semantics.md

Le 20 juin 2024 à 13:08, Vincent de Lau <vincent@delau.nl> a écrit :

From: Gina P. Banyard <internals@gpb.moe>
Sent: Wednesday, June 19, 2024 5:08 PM

On Tuesday, 18 June 2024 at 17:37, Robert Landers
<landers.robert@gmail.com> wrote:

Hello internals,

[...]

What are your thoughts?

As self-proclaimed leading expert on PHP type juggling.
That it is a terrible idea with no gains whatsoever.
Renaming the declare statement does not improve the situation.

PS. Personally, I would rather unify non-strict and strict in some way
that makes sense ... so, that route sounds nice too.

See my old meta RFC: GitHub - Girgias/unify-typing-modes-rfc: PHP RFC: Unify PHP's typing modes

It is a somewhat known hot take from mine that I think the strict_type
declare statement was a mistake. [1]
Mainly because it affects barely nothing in regard to the engine.

I have written/co-authored multiple RFCs over the years to make the
default coercion mode less whack. [2][3][4][5][6][7]
And my container/offset RFC is in the same vein [8] which lead me into a
different rabbit hole then the one I was expecting to explore which is
addressing PHP's weird comparison semantics. [9]

Therefore, I would rather we focus on *actually* fixing PHP's semantics,
than arguing about changing the name of something that shouldn't really
exist in the first place.

Talking about 'going back in time' and sanitizing type coercion, I immediately had to think about the rejected 'Coercive Types for Function Arguments' RFC Zeev created as an alternative to the 'Scalar Type Declaration' RFC which was ultimately chosen and implemented.

PHP: rfc:coercive_sth

It seems that parts of what that RFC suggested have been implemented over time. In retrospect maybe this should have been the direction?

Hi,

The RFC you are pointing to was about introducing a new, more restrictive (and saner) set of automatic coercion rules in the context of function arguments *only*. For instance, `substr('xy', 1.2)` would have been deprecated, but `3 % 1.2` and `['x', 'y'][1.2]` would have continued to “work” (for some stretchy definition of “work”).

What has been implemented over time, is making the existing set of automatic coercion rules more restrictive (and saner) in *all* contexts. For instance, all of `substr('xy', 1.2)`, `3 % 1.2` and `['x', 'y'][1.2]` are deprecated.

—Claude

On 19/06/2024 16:34, Larry Garfield wrote:

Also, as someone who does put every file into strict mode as a matter of
  course, and appreciates the many languages that do not even have a
concept of non-strict mode (like Go or Rust), I really don't appreciate
the backhanded comments in this thread about people who, you know, care
about type safety. (Something that weak mode, when it was introduced in
  PHP 7, only marginally provided if at all.) Strict mode prevents bugs,
  full stop, and we should not fault anyone for applying that bug-stopper
  tool liberally.

Used correctly, it absolutely does. Used incorrectly, it can actually end up *hiding* errors.

I've seen lots of cases where code like this:

some_function_expecting_int($_GET['foo']);

Gets changed to this:

declare(strict_types=1);
some_function_expecting_int( (int)$_GET['foo'] );

Even in PHP 7.0, the first version is actually *stricter* than the second, because explicit casts never fail, but parameter coercion (mode 0) always failed for strings like "hello"; as of 8.0, it also fails for strings like "123foo" and "".

And this is exactly the kind of code that coercive type hints were intended for - HTTP is a text-based protocol, so most PHP applications are dealing with string input and output *all the time*.

One of the things the language badly needs, and I have been trying to come up with a proposal for, is strict type casts, so that this code can actually be written safely but still concisely.

Regards,

--
Rowan Tommins
[IMSoP]

On Fri, Jun 21, 2024 at 10:12 AM Paul Dragoonis <dragoonis@gmail.com> wrote:

On Thu, Jun 20, 2024 at 11:54 PM Rowan Tommins [IMSoP] <imsop.php@rwec.co.uk> wrote:

On 19/06/2024 16:34, Larry Garfield wrote:

Also, as someone who does put every file into strict mode as a matter of
 course, and appreciates the many languages that do not even have a 
concept of non-strict mode (like Go or Rust), I really don't appreciate 
the backhanded comments in this thread about people who, you know, care 
about type safety.  (Something that weak mode, when it was introduced in
 PHP 7, only marginally provided if at all.)  Strict mode prevents bugs,
 full stop, and we should not fault anyone for applying that bug-stopper
 tool liberally.

Hey Rowan,

I meant Hey Robert, but half replying to Rowan’s suggestions too.

What Gina, Larry and Sebastian said.

My $0.02 is

  1. typing “declare(strict_types=1);” is already cumbersome enough, we don’t need to be adding more words and complexity to it

  2. adding the word “coerce” or “coercion” to a thing is really not good from a DX (developer experience) perspective. It will not add clarity it will add confusion… “What is this coersion thing I’ve never heard of”

  3. remember who the target audience is… Rust and Golang are not beginner-friendly or entry-level languages, so the fact you’re even using Rust means you know what you’re doing and likely know what coersion is

3.1 PHP’s strength is that it’s beginner friendly and by that I mean just remember a significant portion of our userbase are Wordpress developers (and Drupal / Magento alike) … and many WP devs won’t have even heard of Dependency Injection before nevermind the complexities of type coersion, so we need to keep things simple as possible at all times

  1. I think the solution you’re looking here for is better education to the end-users, on what the implications of X or Y are … rather than changing the language itself … so the merits of your proposal are good, in that it helps the end-user understand the system better … it’s just the solution you’re proposing here just isn’t it (so far).

Used correctly, it absolutely does. Used incorrectly, it can actually end up hiding errors.

I’ve seen lots of cases where code like this:

some_function_expecting_int($_GET[‘foo’]);

Gets changed to this:

declare(strict_types=1);
some_function_expecting_int( (int)$_GET[‘foo’] );

Even in PHP 7.0, the first version is actually stricter than the second, because explicit casts never fail, but parameter coercion (mode 0) always failed for strings like “hello”; as of 8.0, it also fails for strings like “123foo” and “”.

And this is exactly the kind of code that coercive type hints were intended for - HTTP is a text-based protocol, so most PHP applications are dealing with string input and output all the time.

One of the things the language badly needs, and I have been trying to come up with a proposal for, is strict type casts, so that this code can actually be written safely but still concisely.

Regards,

-- 
Rowan Tommins
[IMSoP]

On Thu, Jun 20, 2024 at 11:54 PM Rowan Tommins [IMSoP] <imsop.php@rwec.co.uk> wrote:

On 19/06/2024 16:34, Larry Garfield wrote:

Also, as someone who does put every file into strict mode as a matter of
 course, and appreciates the many languages that do not even have a 
concept of non-strict mode (like Go or Rust), I really don't appreciate 
the backhanded comments in this thread about people who, you know, care 
about type safety.  (Something that weak mode, when it was introduced in
 PHP 7, only marginally provided if at all.)  Strict mode prevents bugs,
 full stop, and we should not fault anyone for applying that bug-stopper
 tool liberally.

Hey Rowan,

What Gina, Larry and Sebastian said.

My $0.02 is

  1. typing “declare(strict_types=1);” is already cumbersome enough, we don’t need to be adding more words and complexity to it

  2. adding the word “coerce” or “coercion” to a thing is really not good from a DX (developer experience) perspective. It will not add clarity it will add confusion… “What is this coersion thing I’ve never heard of”

  3. remember who the target audience is… Rust and Golang are not beginner-friendly or entry-level languages, so the fact you’re even using Rust means you know what you’re doing and likely know what coersion is

3.1 PHP’s strength is that it’s beginner friendly and by that I mean just remember a significant portion of our userbase are Wordpress developers (and Drupal / Magento alike) … and many WP devs won’t have even heard of Dependency Injection before nevermind the complexities of type coersion, so we need to keep things simple as possible at all times

  1. I think the solution you’re looking here for is better education to the end-users, on what the implications of X or Y are … rather than changing the language itself … so the merits of your proposal are good, in that it helps the end-user understand the system better … it’s just the solution you’re proposing here just isn’t it (so far).

Used correctly, it absolutely does. Used incorrectly, it can actually end up hiding errors.

I’ve seen lots of cases where code like this:

some_function_expecting_int($_GET[‘foo’]);

Gets changed to this:

declare(strict_types=1);
some_function_expecting_int( (int)$_GET[‘foo’] );

Even in PHP 7.0, the first version is actually stricter than the second, because explicit casts never fail, but parameter coercion (mode 0) always failed for strings like “hello”; as of 8.0, it also fails for strings like “123foo” and “”.

And this is exactly the kind of code that coercive type hints were intended for - HTTP is a text-based protocol, so most PHP applications are dealing with string input and output all the time.

One of the things the language badly needs, and I have been trying to come up with a proposal for, is strict type casts, so that this code can actually be written safely but still concisely.

Regards,

-- 
Rowan Tommins
[IMSoP]