Hello.
I’m Saki Takamachi.
Inspired by the issue below, I'm thinking of proposing this RFC.
https://github.com/php/php-src/issues/12055
As the documentation below states, PHP's internal functions currently ignore strict_types.
https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.strict
I think the current spec is not intuitive,
so I propose changing the behavior of the macro ZEND_ARG_USES_STRICT_TYPES() to allow internal functions to accept strict_types.
I plan to make changes in zend_compile.h and zend_compile.c and do the changes myself, I haven't written any tests yet, but I'm thinking about making changes like this.
https://github.com/SakiTakamachi/php-src/pull/1
As per How To Create an RFC, I will first try to gauge response to this proposal on the mailing list.
Thank you
Saki Takamachi
Hello.
I’m Saki Takamachi.
Inspired by the issue below, I'm thinking of proposing this RFC.
https://github.com/php/php-src/issues/12055As the documentation below states, PHP's internal functions currently
ignore strict_types.https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.strict
I think the current spec is not intuitive,
so I propose changing the behavior of the macro
ZEND_ARG_USES_STRICT_TYPES() to allow internal functions to accept
strict_types.I plan to make changes in zend_compile.h and zend_compile.c and do the
changes myself, I haven't written any tests yet, but I'm thinking about
making changes like this.
https://github.com/SakiTakamachi/php-src/pull/1As per How To Create an RFC, I will first try to gauge response to this
proposal on the mailing list.Thank you
Saki Takamachi
Heya!
I was not aware that strict types didn't work here. While I'm 100% behind
the idea, I am afraid that changing this will break code in currently
strict files where the assumption was made that it already worked like
that. It would probably have to give deprecation notices first, and then
possibly a warning or removal in the next major to be feasible.
Heya!
I was not aware that strict types didn't work here. While I'm 100% behind
the idea, I am afraid that changing this will break code in currently
strict files where the assumption was made that it already worked like
that. It would probably have to give deprecation notices first, and then
possibly a warning or removal in the next major to be feasible.
Hi, Thank you for confirming!
Admittedly, it might be better to have some stages rather than a sudden change in 8.4.
saki
Le 29 août 2023 à 02:46, Saki Takamachi saki@sakiot.com a écrit :
Hello.
I’m Saki Takamachi.
Inspired by the issue below, I'm thinking of proposing this RFC.
https://github.com/php/php-src/issues/12055As the documentation below states, PHP's internal functions currently ignore strict_types.
https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.strictI think the current spec is not intuitive,
so I propose changing the behavior of the macro ZEND_ARG_USES_STRICT_TYPES() to allow internal functions to accept strict_types.I plan to make changes in zend_compile.h and zend_compile.c and do the changes myself, I haven't written any tests yet, but I'm thinking about making changes like this.
https://github.com/SakiTakamachi/php-src/pull/1As per How To Create an RFC, I will first try to gauge response to this proposal on the mailing list.
Thank you
Saki Takamachi
Hi,
The larger issue is that higher-order functions do not inherit the strict_types
mode from its calling code, and this is not specific to internal functions.
If you intend to change that for internal functions (with proper deprecation period, of course), you might consider making such a behaviour also possible for userland functions (probably using some opt-in); so that future higher-order internal functions do not become impossible to polyfill.
—Claude
Hi,
The larger issue is that higher-order functions do not inherit the
strict_types
mode from its calling code, and this is not specific to internal functions.If you intend to change that for internal functions (with proper deprecation period, of course), you might consider making such a behaviour also possible for userland functions (probably using some opt-in); so that future higher-order internal functions do not become impossible to polyfill.
—Claude
Hi, thank you for confirming.
If you simply put the problem you pointed out in the code, would it be something like this?
https://gist.github.com/SakiTakamachi/8292dbfe92a2029a6c7b506b12296b7d
Admittedly, I don't think this is intuitive either.
However, if you always inherit the strict_types of the PHP file that is the starting point of processing, in most frameworks the settings in “index.php" will affect everything.
When considering the inheritance of strict_types, I think that it should be an attribute that can be set in “php.ini" instead of being specified for each file.
What do you think?
saki
Le 29 août 2023 à 15:19, Saki Takamachi saki@sakiot.com a écrit :
Hi,
The larger issue is that higher-order functions do not inherit the
strict_types
mode from its calling code, and this is not specific to internal functions.If you intend to change that for internal functions (with proper deprecation period, of course), you might consider making such a behaviour also possible for userland functions (probably using some opt-in); so that future higher-order internal functions do not become impossible to polyfill.
—Claude
Hi, thank you for confirming.
If you simply put the problem you pointed out in the code, would it be something like this?
https://gist.github.com/SakiTakamachi/8292dbfe92a2029a6c7b506b12296b7dAdmittedly, I don't think this is intuitive either.
That might not be intuitive to you, but it follows directly from the specified semantics: whether a function is called in strict_types
mode or not, depends only on where the function is called. I personally doubt that there is an easy way to adjust the rule in order to make it both “intuitive” and simple.
[...]
When considering the inheritance of strict_types, I think that it should be an attribute that can be set in “php.ini" instead of being specified for each file.
What do you think?
Beware that there are many third-party packages that have not opted for strict_types=1
; if you enable that mode globally, you might make those packages malfunction.
As I have just checked, among the packages I’ve installed via composer, there are more packages that do not use strict_types=1
, than packages that use it. Among those that don’t use strict_types
, the following ones are fairly common:
google/apiclient
league/oauth2-client
michelf/php-markdown
microsoft/microsoft-graph
phpmailer/phpmailer
phpoffice/phpspreadsheet
phpseclib/phpseclib
—Claude
maybe we could do a
declare(internal_strict_types=1);
on a per-file basis just like the existing userland strict_types?
(name is up for bikeshedding ofc)
Le 29 août 2023 à 15:19, Saki Takamachi saki@sakiot.com a écrit :
Hi,
The larger issue is that higher-order functions do not inherit the
strict_types
mode from its calling code, and this is not specific to internal functions.If you intend to change that for internal functions (with proper deprecation period, of course), you might consider making such a behaviour also possible for userland functions (probably using some opt-in); so that future higher-order internal functions do not become impossible to polyfill.
—Claude
Hi, thank you for confirming.
If you simply put the problem you pointed out in the code, would it be something like this?
https://gist.github.com/SakiTakamachi/8292dbfe92a2029a6c7b506b12296b7dAdmittedly, I don't think this is intuitive either.
That might not be intuitive to you, but it follows directly from the specified semantics: whether a function is called in
strict_types
mode or not, depends only on where the function is called. I personally doubt that there is an easy way to adjust the rule in order to make it both “intuitive” and simple.[...]
When considering the inheritance of strict_types, I think that it should be an attribute that can be set in “php.ini" instead of being specified for each file.
What do you think?
Beware that there are many third-party packages that have not opted for
strict_types=1
; if you enable that mode globally, you might make those packages malfunction.As I have just checked, among the packages I’ve installed via composer, there are more packages that do not use
strict_types=1
, than packages that use it. Among those that don’t usestrict_types
, the following ones are fairly common:google/apiclient
league/oauth2-client
michelf/php-markdown
microsoft/microsoft-graph
phpmailer/phpmailer
phpoffice/phpspreadsheet
phpseclib/phpseclib—Claude
--
To unsubscribe, visit: https://www.php.net/unsub.php
- I think most code actually using strict_types=1 is built with the
assumption that internal functions use strict too, so it's entirely
possible that the backwards-compatibility issue is so small that we
can get away with internal functions just inheriting the userland
strict_types
maybe we could do a
declare(internal_strict_types=1);
on a per-file basis just like the existing userland strict_types?
(name is up for bikeshedding ofc)Le 29 août 2023 à 15:19, Saki Takamachi saki@sakiot.com a écrit :
Hi,
The larger issue is that higher-order functions do not inherit the
strict_types
mode from its calling code, and this is not specific to internal functions.If you intend to change that for internal functions (with proper deprecation period, of course), you might consider making such a behaviour also possible for userland functions (probably using some opt-in); so that future higher-order internal functions do not become impossible to polyfill.
—Claude
Hi, thank you for confirming.
If you simply put the problem you pointed out in the code, would it be something like this?
https://gist.github.com/SakiTakamachi/8292dbfe92a2029a6c7b506b12296b7dAdmittedly, I don't think this is intuitive either.
That might not be intuitive to you, but it follows directly from the specified semantics: whether a function is called in
strict_types
mode or not, depends only on where the function is called. I personally doubt that there is an easy way to adjust the rule in order to make it both “intuitive” and simple.[...]
When considering the inheritance of strict_types, I think that it should be an attribute that can be set in “php.ini" instead of being specified for each file.
What do you think?
Beware that there are many third-party packages that have not opted for
strict_types=1
; if you enable that mode globally, you might make those packages malfunction.As I have just checked, among the packages I’ve installed via composer, there are more packages that do not use
strict_types=1
, than packages that use it. Among those that don’t usestrict_types
, the following ones are fairly common:google/apiclient
league/oauth2-client
michelf/php-markdown
microsoft/microsoft-graph
phpmailer/phpmailer
phpoffice/phpspreadsheet
phpseclib/phpseclib—Claude
--
To unsubscribe, visit: https://www.php.net/unsub.php
Le 29 août 2023 à 18:40, Hans Henrik Bergan divinity76@gmail.com a écrit :
- I think most code actually using strict_types=1 is built with the
assumption that internal functions use strict too, so it's entirely
possible that the backwards-compatibility issue is so small that we
can get away with internal functions just inheriting the userland
strict_typesmaybe we could do a
declare(internal_strict_types=1);
on a per-file basis just like the existing userland strict_types?
(name is up for bikeshedding ofc)[...]
Hi Hans Henrik,
The rule of the mailing list is to post your answer below the text you are answering to, and to strip the parts of the original message that are not relevant to your answer. The aim is to make readers not to guess what you are responding to, and not to read backwards, thanks.
Furthermore, I can’t connect your answer to any of the points I made in the specific email you replied to, so that you may have replied to the wrong email.
—Claude
That might not be intuitive to you, but it follows directly from the specified semantics: whether a function is called in
strict_types
mode or not, depends only on where the function is called. I personally doubt that there is an easy way to adjust the rule in order to make it both “intuitive” and simple.
On second thought based on your point, it seems confusing to change the behavior of strict_types only for calls from internal functions.
A minor problem is that there is no way to control strict_types for calls from internal functions.
Saki
As the documentation below states, PHP's internal functions currently ignore strict_types.
https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.strict
Just to be really clear, it is not true that internal functions "ignore"
the setting; they behave exactly the same as any userland function which
was declared in strict_types=0 mode.
The warning in the manual is actually a consequence of the following
Note (perhaps the order should be reversed?):
- Strict typing applies to function calls made from within the file
with strict typing enabled - Function calls from within internal functions will not be affected by
the |strict_types| declaration
To clarify the scenario, imagine three files:
/* a.php */
declare(strict_types=0);
function call_me_back(callable $f, mixed $input) {
$f($input);
}
/* b.php */
declare(strict_types=1);
function output_me(string $output) {
echo "$output\n";
}
/* c.php */
declare(strict_types=1);
call_me_back( output_me(...), 42 );
The only calls that happen are:
- A call from c.php to call_me_back; c.php is in strict_types=1 mode,
so the parameters $f and $input will not be coerced - A call from a.php to output_me; a.php is in strict_types=0 mode, so
the parameter $output will be coerced to a string
The behaviour of internal functions like array_filter is exactly the
same - array_filter is the caller, and it is defined in strict_types=0
mode, just like call_me_back above; the mode set in any other code is
irrelevant, because it is not the caller.
As Claude Pache, it's actually very difficult to design a version of the
feature that would be fully intuitive in this case - if I write the
below, does the caller of wrapped_array_filter still get to control the
mode that call_me_back is run under?
function call_me_back(int $value) {
return $value <= 42;
}
function backwards_array_filter(array $array, ?callable $callback =
null, int $mode = 0): array {
return array_reverse( array_filter($array, $callback, $mode) );
}
// In another file:
var_dump( backwards_array_filter($some_array, call_me_back(...)) );
Regards,
--
Rowan Tommins
[IMSoP]