Hello internals,
Máté Kocsis and myself would like to propose deprecating implicitly nullable parameter types.
The RFC is available on the wiki at the following address:
https://wiki.php.net/rfc/deprecate-implicitly-nullable-types
Best regards,
Gina P. Banyard
Hello internals,
Máté Kocsis and myself would like to propose deprecating implicitly
nullable parameter types.The RFC is available on the wiki at the following address:
https://wiki.php.net/rfc/deprecate-implicitly-nullable-typesBest regards,
Gina P. Banyard
--
To unsubscribe, visit: https://www.php.net/unsub.php
From a quick glance this looks like it would be very difficult to implement
without completely redoing default optional parameters as a whole.
Hello internals,
Máté Kocsis and myself would like to propose deprecating implicitly
nullable parameter types.The RFC is available on the wiki at the following address:
https://wiki.php.net/rfc/deprecate-implicitly-nullable-typesBest regards,
Gina P. Banyard
--
To unsubscribe, visit: https://www.php.net/unsub.php
Also just did a quick test, and i don't believe this would be possible. It
would remove functionality from the language widely used.
As you are mistaking iint $var = null
params as "nullable". Which they
are not, they are "optional default" parameters. The equals
can be succeeded by any value, to set the parameter to such variable where
the parameter is not passed. int ?$arg
is not provided as
an alternative, the directive int ?$arg
simple allows the parameters to
be passed as null, it is still required to pass through the
parameter.
To clarify
T ?$var
= Requires the parameter to be passed to the function, null
value allowed
T $var = null
= Does not require the parameter to be passed to the
function, is set to null if not.
I fully support this. I even wanted to propose this RFC myself. Implicitly
nullable parameters are extremely confusing in PHP 8 and they are very easy
to replace.
Hello internals,
Máté Kocsis and myself would like to propose deprecating implicitly
nullable parameter types.The RFC is available on the wiki at the following address:
https://wiki.php.net/rfc/deprecate-implicitly-nullable-typesBest regards,
Gina P. Banyard
--
To unsubscribe, visit: https://www.php.net/unsub.php
Also just did a quick test, and i don't believe this would be possible. It
would remove functionality from the language widely used.
As you are mistakingiint $var = null
params as "nullable". Which they
are not, they are "optional default" parameters. The equals
can be succeeded by any value, to set the parameter to such variable where
the parameter is not passed.int ?$arg
is not provided as
an alternative, the directiveint ?$arg
simple allows the parameters to
be passed as null, it is still required to pass through the
parameter.To clarify
T ?$var
= Requires the parameter to be passed to the function, null
value allowed
T $var = null
= Does not require the parameter to be passed to the
function, is set to null if not.
Your example contains int2
as type with a default value of null
. This
works because it implicitly marks the class int2
as nullable. If you were
to set this default value to 1
via int2 $int2 = 1
it breaks with "Fatal
error: Cannot use int as default value for parameter $int2 of type int2"
Anyhow, = null
implicitly makes the parameter nullable even if the type
doesn't specify it's nullable. The argument is that if the type isn't
nullable, then the default value may not be null either.
As you are mistaking
iint $var = null
params as "nullable". Which they
are not, they are "optional default" parameters.
The feature which is being discussed is that, for the specific case of "= null", the parameter is made both optional and nullable.
To make it clearer, the following all declare default values within the allowed type:
int $foo = 1
int|string $foo = 'hello'
?int $foo = 1
?int $foo = null
The following all lead to a type error, because the default value isn't allowed for the declared type:
int $foo = 'hello'
int|string $foo = new DateTime;
?int $foo = 'hello'
However, there is a special case: for purely historical reasons, a default of null is allowed even when it doesn't match the declared type:
int $foo = null
int|string $foo = null
These are processed as though they were declared as nullable types; and the fix for the proposed deprecation would be to do so:
?int $foo = null
int|string|null $foo = null
The fact that the feature is tricky to explain is a good reason to deprecate it, and I think I support the proposal unless I see a good argument against.
Regards,
--
Rowan Tommins
[IMSoP]
Hello internals,
Máté Kocsis and myself would like to propose deprecating implicitly
nullable parameter types.The RFC is available on the wiki at the following address:
https://wiki.php.net/rfc/deprecate-implicitly-nullable-typesBest regards,
Gina P. Banyard
--
To unsubscribe, visit: https://www.php.net/unsub.php
I just encountered this language inconsistency when trying to remove
nullable from a constructor-promoted property:
class MyClass
{
public function __construct(
public ?string $title = null // removing "?" here causes "Fatal
error: Cannot use null as default value"
) {
$this->title = $title ?: resolveTitle();
}
}
Which is fine, there's a simple workaround, it was just surprising.
I just encountered this language inconsistency when trying to remove
nullable from a constructor-promoted property:class MyClass { public function __construct( public ?string $title = null // removing "?" here causes "Fatal error: Cannot use null as default value" ) { $this->title = $title ?: resolveTitle(); } }
Which is fine, there's a simple workaround, it was just surprising.
Property types don't infer nullability from the default value being
null, so constructor properties don't allow it either. I'd say this is
not an inconsistency, but rather a consistency with what this RFC
proposes to deprecate and remove.
Highly supportive of this RFC :)
Hello internals,
Máté Kocsis and myself would like to propose deprecating implicitly
nullable parameter types.The RFC is available on the wiki at the following address:
https://wiki.php.net/rfc/deprecate-implicitly-nullable-typesBest regards,
Gina P. Banyard
I am in support of this change. My only concern is timeline. This RFC would deprecate it in 8.4, and presumably support would be removed in 9.0. While we haven't discussed a timeline for 9.0, historically the pattern is every 5 years, which would put 9.0 after 8.4, which means only one year of deprecation notices for this change.
Given the massive amount of code that built up between 5.1 and 7.1, and 7.1 and today, I worry that a year won't be enough time for legacy code to clean up and it would be another "OMG you broke everything you evil Internals <expletive deleted>!" like the "undefined is now warning" changes in 8.0. (In both cases, well-written code any time from the past decade has no issue but well-written code is seemingly the minority.)
The RFC notes that PHPStan and friends have an easy flag to make the change, which is great, but still that's a minority of PHP devs that even know to use static analysis.
The only solution I can think of is to keep the deprecation in place until PHP 10, but that's a very long time from now and the RFC says this simplifies a decent amount of engine code, so I'm not wild about that idea. I am open to alternate suggestions for how we can make this transition more graceful.
Again, fully support the change, I just want to make sure it's graceful.
--Larry Garfield
The only solution I can think of is to keep the deprecation in place
until PHP 10, but that's a very long time from now and the RFC says this
simplifies a decent amount of engine code, so I'm not wild about that idea.
Another solution is to have version 8.5. Also given the fact that much of
the deprecated code will be removed in PHP 9.0, maybe it's worth discussing
how long should be period between 9 and 10?
Kind regards,
Jorg Sowa
The only solution I can think of is to keep the deprecation in place
until PHP 10, but that's a very long time from now and the RFC says this
simplifies a decent amount of engine code, so I'm not wild about that idea.Another solution is to have version 8.5. Also given the fact that much of
the deprecated code will be removed in PHP 9.0, maybe it's worth discussing
how long should be period between 9 and 10?Kind regards,
Jorg Sowa
I've argued several times that the ecosystem would benefit greatly from having scheduled majors. It would make planning around deprecations vastly easier, for instance. So far, that's fallen on deaf ears.
--Larry Garfield
On Mon, Jan 22, 2024 at 12:54 PM Larry Garfield larry@garfieldtech.com
wrote:
I am in support of this change. My only concern is timeline. This RFC
would deprecate it in 8.4, and presumably support would be removed in 9.0.
While we haven't discussed a timeline for 9.0, historically the pattern is
every 5 years, which would put 9.0 after 8.4, which means only one year of
deprecation notices for this change.
This is... not true. There is literally no established pattern for when
major releases take place, either by length of time, or number of minor
releases.
PHP 3 had no minor releases. PHP 4 had 4 minor releases before PHP 5
dropped, and then a minor release happened AFTER PHP 5 was already in the
wild (4.4). PHP 5 had 7 minor releases, with MULTIPLE YEARS between some of
the minor releases before the current process was adopted towards the end
of its lifecycle.
We are moving TOWARDS a fairly standard process, but there's no definite
plans for PHP 9 to follow after 8.4 as of yet, and the process does not
require it.
Given the massive amount of code that built up between 5.1 and 7.1, and
7.1 and today, I worry that a year won't be enough time for legacy code to
clean up and it would be another "OMG you broke everything you evil
Internals <expletive deleted>!" like the "undefined is now warning" changes
in 8.0. (In both cases, well-written code any time from the past decade
has no issue but well-written code is seemingly the minority.)
But I DO agree with the above. So this might be a time for us to start
discussing if/when we want a PHP 9 to occur.
--
Matthew Weier O'Phinney
mweierophinney@gmail.com
https://mwop.net/
he/him
On Mon, Jan 22, 2024 at 12:54 PM Larry Garfield larry@garfieldtech.com
wrote:I am in support of this change. My only concern is timeline. This RFC
would deprecate it in 8.4, and presumably support would be removed in 9.0.
While we haven't discussed a timeline for 9.0, historically the pattern is
every 5 years, which would put 9.0 after 8.4, which means only one year of
deprecation notices for this change.This is... not true. There is literally no established pattern for when
major releases take place, either by length of time, or number of minor
releases.PHP 3 had no minor releases. PHP 4 had 4 minor releases before PHP 5
dropped, and then a minor release happened AFTER PHP 5 was already in the
wild (4.4). PHP 5 had 7 minor releases, with MULTIPLE YEARS between some of
the minor releases before the current process was adopted towards the end
of its lifecycle.We are moving TOWARDS a fairly standard process, but there's no definite
plans for PHP 9 to follow after 8.4 as of yet, and the process does not
require it.
I know there's no official statement regarding timeline. However, 5.3 (aka PHP 6) -> PHP 7 was 5 years. PHP 7 -> PHP 8 was 5 years. It's not unreasonable for folks to assume 9 comes 5 years after 8, whether that's the intention or not. Given the lengths of time involved there's not a great many data points to work from, but humans gonna pattern match. :-)
In any case, my core point is a deprecation of this impact probably needs more than a year's lead time before it's actually removed. If we agree on that, we should plan around that and actually, you know, plan.
Given the massive amount of code that built up between 5.1 and 7.1, and
7.1 and today, I worry that a year won't be enough time for legacy code to
clean up and it would be another "OMG you broke everything you evil
Internals <expletive deleted>!" like the "undefined is now warning" changes
in 8.0. (In both cases, well-written code any time from the past decade
has no issue but well-written code is seemingly the minority.)But I DO agree with the above. So this might be a time for us to start
discussing if/when we want a PHP 9 to occur.
--Larry Garfield
I am in support of this change. My only concern is timeline. This RFC would deprecate it in 8.4, and presumably support would be removed in 9.0. While we haven't discussed a timeline for 9.0, historically the pattern is every 5 years, which would put 9.0 after 8.4, which means only one year of deprecation notices for this change.
There is no reason as to why 9.0 should come after 8.4, and I fundamentally disagree with the logic that we somehow need to "plan" deprecations around how much time we need to provide users to upgrade.
To this day, I have never been provided any evidence that longer deprecation times actually lead to users upgrading their code sooner and not delay the inevitable.
We were even told to shunt mass deprecation RFCs for 8.0 to 8.1, effectively reducing how much time users have to upgrade for the sake of simplifying the migration from 7.4 to 8.0.
The idea for this RFC was floated around the time of PHP 7.4, but this was deemed too soon due to cross version compatibility.
Moreover, asking core developers to magically figure out all the various ways PHP is bonkers or broken in a specific narrow time frame, just so userland can have X version where the deprecation exists until removal, is unreasonable.
If this is the model that we should seek, then we should completely move away from our current versioning system and do something more like Python that provides 2 version where a feature is deprecated before removing support.
E.g. features deprecated in Python 3.9 were removed in Python 3.11.
As such, I will not entertain this idea of timelines and when it is the "right time" to deprecate something for it to be removed at the "right time".
If this is something people feel strongly, an RFC to change what our versioning is and means should be done instead.
Given the massive amount of code that built up between 5.1 and 7.1, and 7.1 and today, I worry that a year won't be enough time for legacy code to clean up and it would be another "OMG you broke everything you evil Internals <expletive deleted>!" like the "undefined is now warning" changes in 8.0. (In both cases, well-written code any time from the past decade has no issue but well-written code is seemingly the minority.)
I find this comparison disingenuous, fixing undefined variables is one, if not two orders of magnitude harder than fixing this issue.
Fixing implicit null to scalar types coercions for internal functions causes way more havoc than this for legacy codebases, and yet we have consistently maintained the rationale for the deprecation.
While I do take into consideration the impact RFCs can have on existing code bases, I consider having clear, easy, and comprehensible semantics to be way more important than supporting some complicated and confusing semantics for the sake of BC.
There will always be code running on a completely outdated version of PHP due to whatever reason.
And refusing to fix the language and its semantics for the vast majority of new code that is going to be written in it feels like a bad decision to me.
Especially if fixing it results in engine simplifications.
We are our own project, and we need to make choices for the sake of the health of the project, and this means removing stuff in a reasonable timeline.
I personally don't work on PHP to do legacy maintenance and keep running it at all cost, if I did want to do this I'd be writing COBOL.
I work on PHP because I believe it has a long future ahead of itself, and that new people will learn it and use it.
And forcing those people to need to learn, and remember bazillions of gotchas really doesn't sound fair to them IMHO.
The RFC notes that PHPStan and friends have an easy flag to make the change, which is great, but still that's a minority of PHP devs that even know to use static analysis.
One does not need to use a static analyser to determine or fix this issue, indeed, I didn't even mention static analysers in the RFC as PHP_CS_FIXER is a tool for enforcing coding styles and is capable of fixing this issue.
This tool and other code formatting tools are used more widely and for longer than static analysers.
Best regards,
Gina P. Banyard
The RFC notes that PHPStan and friends have an easy flag to make the change, which is great, but still that's a minority of PHP devs that even know to use static analysis.
One does not need to use a static analyser to determine or fix this issue, indeed, I didn't even mention static analysers in the RFC as PHP_CS_FIXER is a tool for enforcing coding styles and is capable of fixing this issue.
This tool and other code formatting tools are used more widely and for longer than static analysers.
While I concur that too few devs use the helpful tooling available to
them, I can already tell you that PHPCompatibility for PHP_CodeSniffer
will be able to detect and flag code subject to this deprecation without
problems and I will make sure the sniff is available ahead of the PHP
8.4 release (providing the RFC passes).
And the Slevomat Coding Standard for PHP_CodeSniffer already contains
the SlevomatCodingStandard.TypeHints.NullableTypeForNullDefaultValue
sniff to auto-fix non-nullable typed parameters with a null
default
value to be nullable typed as well, so it's not just CS-Fixer which can
help with this.
Smile,
Juliette
The RFC notes that PHPStan and friends have an easy flag to make the change, which is great, but still that's a minority of PHP devs that even know to use static analysis.
One does not need to use a static analyser to determine or fix this issue, indeed, I didn't even mention static analysers in the RFC as PHP_CS_FIXER is a tool for enforcing coding styles and is capable of fixing this issue.
This tool and other code formatting tools are used more widely and for longer than static analysers.While I concur that too few devs use the helpful tooling available to
them, I can already tell you that PHPCompatibility for PHP_CodeSniffer
will be able to detect and flag code subject to this deprecation without
problems and I will make sure the sniff is available ahead of the PHP
8.4 release (providing the RFC passes).And the Slevomat Coding Standard for PHP_CodeSniffer already contains
theSlevomatCodingStandard.TypeHints.NullableTypeForNullDefaultValue
sniff to auto-fix non-nullable typed parameters with anull
default
value to be nullable typed as well, so it's not just CS-Fixer which can
help with this.
I had a hunch that PHP_CodeSniffer was able to handle this already, I just couldn't find the correct sniff. :)
I'll mention it if/when I update the RFC text.
Best regards,
Gina P. Banyard
On Monday, 22 January 2024 at 18:53, Larry Garfield
larry@garfieldtech.com wrote:I am in support of this change. My only concern is timeline. This RFC would deprecate it in 8.4, and presumably support would be removed in 9.0. While we haven't discussed a timeline for 9.0, historically the pattern is every 5 years, which would put 9.0 after 8.4, which means only one year of deprecation notices for this change.
There is no reason as to why 9.0 should come after 8.4, and I
fundamentally disagree with the logic that we somehow need to "plan"
deprecations around how much time we need to provide users to upgrade.
To this day, I have never been provided any evidence that longer
deprecation times actually lead to users upgrading their code sooner
and not delay the inevitable.
We were even told to shunt mass deprecation RFCs for 8.0 to 8.1,
effectively reducing how much time users have to upgrade for the sake
of simplifying the migration from 7.4 to 8.0.The idea for this RFC was floated around the time of PHP 7.4, but
this was deemed too soon due to cross version compatibility.Moreover, asking core developers to magically figure out all the
various ways PHP is bonkers or broken in a specific narrow time frame,
just so userland can have X version where the deprecation exists until
removal, is unreasonable.
If this is the model that we should seek, then we should completely
move away from our current versioning system and do something more like
Python that provides 2 version where a feature is deprecated before
removing support.
E.g. features deprecated in Python 3.9 were removed in Python 3.11.As such, I will not entertain this idea of timelines and when it is the
"right time" to deprecate something for it to be removed at the "right
time".If this is something people feel strongly, an RFC to change what our
versioning is and means should be done instead.Given the massive amount of code that built up between 5.1 and 7.1, and 7.1 and today, I worry that a year won't be enough time for legacy code to clean up and it would be another "OMG you broke everything you evil Internals <expletive deleted>!" like the "undefined is now warning" changes in 8.0. (In both cases, well-written code any time from the past decade has no issue but well-written code is seemingly the minority.)
I find this comparison disingenuous, fixing undefined variables is one,
if not two orders of magnitude harder than fixing this issue.
Fixing implicit null to scalar types coercions for internal functions
causes way more havoc than this for legacy codebases, and yet we have
consistently maintained the rationale for the deprecation.While I do take into consideration the impact RFCs can have on existing
code bases, I consider having clear, easy, and comprehensible semantics
to be way more important than supporting some complicated and confusing
semantics for the sake of BC.
There will always be code running on a completely outdated version of
PHP due to whatever reason.
And refusing to fix the language and its semantics for the vast
majority of new code that is going to be written in it feels like a bad
decision to me.
Especially if fixing it results in engine simplifications.We are our own project, and we need to make choices for the sake of the
health of the project, and this means removing stuff in a reasonable
timeline.
I personally don't work on PHP to do legacy maintenance and keep
running it at all cost, if I did want to do this I'd be writing COBOL.
I work on PHP because I believe it has a long future ahead of itself,
and that new people will learn it and use it.
And forcing those people to need to learn, and remember bazillions of
gotchas really doesn't sound fair to them IMHO.
... I think you're grossly misreading my post. I reiterate: I support this change. I like it. I want it to happen. I am not proposing that we support broken old code indefinitely, nor have I ever done so.
But,
I fundamentally disagree with the logic that we somehow need to "plan"
deprecations around how much time we need to provide users to upgrade.
I categorically disagree here. PHP has a terrible reputation, even among its own boosters, for breaking people's stuff and making upgrades harder. That is partially deserved, partially not. (I've written in defense of Internals' improvements extensively.) But as a project we need to consider both the practical and social impact of any breaking changes.
You assert that this is 1-2 orders of magnitude less impactful than undefined vars or null string params were. I have no data on that off hand either way, so cannot confirm or deny that estimate. (If you do, that would be very helpful. No sarcasm, it really would.) It is definitely more tooling-handleable, and it sounds like there's ample existing tooling for it, so that's great and will help, but as we've noted many times, people using good tooling are the minority.
Even if this change is vastly smaller than previous flashpoints, my concern is it being large enough that it causes another rukus and more bad PR about "oh those PHP devs breaking everyone's code without any regard for we peons." (cf: https://24daysindecember.net/2022/12/06/evolving-php/) Whether or not that statement is true is irrelevant. If that is the perception, it does harm to the PHP ecosystem.
Will this change be large "enough" to cause a fuss? I don't know. I fear it may be, but I don't know. That's a worthwhile conversation to have, calmly. But a longer deprecation period can help to reduce the fuss. (Not eliminate, but that's not something we can expect. Reduce is enough.)
There is indeed a related discussion around scheduling, deprecation timelines in general, etc. As I said, I've tried to start that discussion in the past and was mostly ignored.
Maybe "all deprecations last for X releases, whatever the number" is a good policy to have; I don't know. Deciding now that there will be an 8.5 and then a 9.0 is also a viable option, which will also give 2 years grace period for users to get up to speed on this change. That's the entire point of deprecations.
What I do not think is a good approach is "meh, we'll deprecate whenever, and remove whenever, we'll tell you when we get there." That's not helpful to our downstream users, without whom there is no project. PHP is at a scale where we have to think about such things. Because every time we give someone a months long upgrade process, users migrate to Go, Node, etc.
We do need to clean up PHP's screwy edge cases, and I'm very glad that you've been working on that for so long. But we also need to better manage that process to minimize the pain for downstream users, or we won't have downstream users. Flippancy about them is counter-productive.
--Larry Garfield
I fundamentally disagree with the logic that we somehow need to "plan"
deprecations around how much time we need to provide users to upgrade.I categorically disagree here. PHP has a terrible reputation, even among its own boosters, for breaking people's stuff and making upgrades harder. That is partially deserved, partially not. (I've written in defense of Internals' improvements extensively.) But as a project we need to consider both the practical and social impact of any breaking changes.
PHP has a terrible reputation because it didn't try to fix any of its crap for years.
PHP has a terrible reputation because it added random ill designed stuff at random prior to the RFC process.
PHP has a terrible reputation because it has insane bonkers semantics.
PHP has a terrible reputation because its image is stuck in 2005.
PHP has a terrible reputation because of projects written in PHP having "bad" codebases.
etc. etc.
I've stopped counting how many times I've been sent "PHP: a fractal of bad design" [1], how many times have people have brought up to me the fact PHP is the only language they know that undeprecated something (for reference is_a()
in 5.1), and other countless stuff that I need to hear semi often.
Internals is blamed for making upgrades hard, the life of library maintainers hell, and everything that could be assigned blame to internals.
But I have never seen internals tell userland to promote deprecations to exceptions, userland came up with this, and uses this as a tool to harass library maintainers.
Maybe I'm just weird, but I don't actually care that projects still use PHP 7, 5, 4, or 3. Because there will always be such projects, and basing my decisions on those makes no sense to me.
It helps that I also hear people that are satisfied and happy with the language being tighter, but those are rarely said publicly, because there is no need to complain online when one has nothing to complain about.
And again, I frankly don't believe that providing 2, 3, 5, 10 years of deprecation before a removal is effectively different from providing 1 year.
People will either fix it immediately, or leave it until the end of time and still make a fuss about it.
You assert that this is 1-2 orders of magnitude less impactful than undefined vars or null string params were. I have no data on that off hand either way, so cannot confirm or deny that estimate. (If you do, that would be very helpful. No sarcasm, it really would.) It is definitely more tooling-handleable, and it sounds like there's ample existing tooling for it, so that's great and will help, but as we've noted many times, people using good tooling are the minority.
I don't need data to know this change is less impactful.
Undefined vars requires either tracking the source of the first usage, or guarding every usage with a null coalesce operator.
Implicit coercions require the same thing, either tracking the source, guarding every usage, or doing the worst option to just chug an explicit cast in front.
And both of these things can happen countless times all over the code base, thus flooding logs.
Compared to this change, which requires changing the unique definition of the offending function/method signature.
I cannot comprehend how at the same time we need to treat users as capable, intelligent, knowledge people when introducing features.
And at the same time consider them to be incompetent, and lacking skills to use tooling.
For this deprecation the tooling already exists, if people don't want to use it, why? If people don't know about it, why? If people don't trust it, why?
This is different from a bunch of other changes where any tooling would be brand new.
There is indeed a related discussion around scheduling, deprecation timelines in general, etc. As I said, I've tried to start that discussion in the past and was mostly ignored.
Maybe "all deprecations last for X releases, whatever the number" is a good policy to have; I don't know. Deciding now that there will be an 8.5 and then a 9.0 is also a viable option, which will also give 2 years grace period for users to get up to speed on this change. That's the entire point of deprecations.
Maybe because fixed major release cycles for a programming language is just a bad idea?
Because what does a "major" release entail for a programming language?
And if someone wants to deprecate something in 8.5 what do we tell them? No?
PHP is an open source project, people come and go, and start contributing at different times. And telling someone nah sorry you should have started contributing 3 years ago to be able to make this change is extremely toxic IMHO?
(c.f. the debacle from last year)
And when thinking of those sorts of policies, the health of the project and its contributors must be front and centre.
If there is no one to maintain, or that wants to maintain PHP, it doesn't matter that there are downstream users or not.
Yes, PHP has the Foundation now, and yes they pay me and others to work on PHP, but I don't think its mere existence means that the project is still not at risk.
And anything that leads to friction for new people to contribute, or existing contributors to burn out, is just bad.
One should be able to improve PHP the moment one starts contributing, regardless of the nature of said improvement.
What I do not think is a good approach is "meh, we'll deprecate whenever, and remove whenever, we'll tell you when we get there." That's not helpful to our downstream users, without whom there is no project. PHP is at a scale where we have to think about such things. Because every time we give someone a months long upgrade process, users migrate to Go, Node, etc.
Implying something could be removed whenever really feels like you are saying we could just remove stuff in 8.4.
Not having a date for PHP 9 is not equivalent to something being removed whenever.
Again, maybe I am just weird, but if the code is in such a state that people rewrite their code, regardless of in another language or not, I see this as a win.
People already migrate to other languages because they don't think PHP is good enough.
Also, am I the only one remembering people wanting a PHP 7.5 with no features and just deprecations or what? This clearly gave me the impression people wanted to get rid of problematic baggage, instead of what has been recently portrayed.
Probably, because for once, it was the other crowd shouting into internals?
Best regards,
Gina P. Banyard
[1] https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/
FWIW I think one year is more than enough of deprecation time for any
change, especially for something so easy as this. It's not like we are
forcing users to upgrade to the newest version as soon as possible. I
still haven't used PHP 8.3, and I most likely will not use it for
another year. In practice, a year of deprecation time is much more for
most of the people.
Additionally, people can start fixing it right now. The tools already
provide such an option and the alternative syntax has been in
existence for some time.
If we find out that the change is being more difficult to implement
than anticipated, the solution would be to postpone the removal.
Deprecation can happen in any version and I see no reason to restrict
this by implementing a new policy. But if anyone would want to do
this, then there should be a separate RFC and discussion for this. In
terms of this RFC, I see no reason not to accept it.
Hello internals,
Máté Kocsis and myself would like to propose deprecating implicitly nullable parameter types.
The RFC is available on the wiki at the following address:
https://wiki.php.net/rfc/deprecate-implicitly-nullable-typesBest regards,
Gina P. Banyard
For what it's worth, I support this deprecation - one less "exception to
the rule" to have to take into account and remember.
As for the RFC:
-
While I don't think the impact will be that large and the fix is
straight-forward, I believe it would still be good to include an impact
analysis
(top 2000 Packagist packages check) in the RFC to confirm this. -
The RFC currently only talks about deprecating the syntax in PHP 8.4
and makes no mention of removing support for the syntax altogether
in the future. Would it be an idea to include a proposal for
removal of the syntax in the RFC ? -
The RFC does not mention the impact of the function signature change
on inheritance. I think it would be good to clarify that there is none.
The changes will not cause an LSP violation in case of inheritance
and can be made for parent/child classes independently of each other.
Also see: https://3v4l.org/0qM7W -
While the majority of projects will (hopefully) be able to use
nullable types/union types with null to mitigate the deprecation,
there are still projects which have a wide range of supported PHP
versions with the minimum being below PHP 7.1 (yes, WordPress I'm
looking at you).It might be worth mentioning in the "Backward incompatible changes"
section what the options are for those projects to mitigate the deprecation.
As far as I can see, that would come down to the following options:- [Best option] Raise the minimum supported PHP version to 7.1,
use nullable types and remove thenull
default value.
Including a code sample like the 3v4l I posted above should
probably also help clarify the expected change to the code. - Removing the default value without making the type nullable.
This would be a signature change and could cause problems
if the parameter was previously optional, but that's for the
project itself to make a judgment call on. - For scalar and array typed parameters, changing the default
value to one which complies with the type. Again, this would
be a signature change and in this case, it could cause
problems if the parameter was previously required and not
the last parameter before optional ones, but again, that's for
the project itself to make a judgment call on. - Remove the type declaration + if the parameter is/was required,
remove the default value. This would be a huge step backwards,
but would still allow for making those signatures
cross-version compatible. This again, would be a signature change and this
would be one which would violate LSP in case of inheritance,
but again, that's for the project itself to make a judgment call on.
- [Best option] Raise the minimum supported PHP version to 7.1,
Hope I've captured all options, though not claiming completeness.
Hope this helps.
Smile,
Juliette
Hi Gina, Máté
Máté Kocsis and myself would like to propose deprecating implicitly
nullable parameter types.
The RFC is available on the wiki at the following address:
https://wiki.php.net/rfc/deprecate-implicitly-nullable-types
Thanks for the RFC.
I have the same concerns as Larry but I don't have any ideas on how to make
the migration more seamless, so personally I'm fine with deprecating in 8.4
and dropping in 9.0.
For the record, Symfony was using the reverse rule (removing the nullable
flag when the default was null already). This was done to reduce the
overall visual debt™, but the arguments in favor of your proposal are sound.
I ran php-cs-fixer on the codebase, you can see the patch here:
https://github.com/symfony/symfony/pull/53612
TL;DR, this is a +/- 2000 lines change that's quite easy to do.
I think the RFC is missing some impact analysis BTW, just to be sure voters
can look at some data to make a best informed decision.
There's one catch-22, which is that I had to manually fix non-optional
arguments with default values (as a reminder, they're deprecated too):
https://github.com/symfony/symfony/pull/53612/commits/fb9fa26102512090550f9137751f81677c06d5f9
Fixing them can be automated too but this is still a separate code
transformation. I think this should be mentioned in the RFC.
The impact on the ecosystem is going to be significant for sure, especially
because of the previous CS of Symfony. But at least the transition has
already started since we merged this in our oldest maintained version.
Cheers,
Nicolas
Hi Nicolas,
Thanks for your input and proactive measures! I've just finished the
analysis
you asked for:
- code: https://gist.github.com/kocsismate/c0d10c820606dfe297f09374aa634df5
- results:
https://gist.github.com/kocsismate/cf3bdfbf35eb10224ee5ecd29b39656b
TLDR: there are 880 packages out of 2000 which use implicit nullable
parameter types.
We will mention this fact in the RFC soon, as well as the need for
additionally taking
care of non-optional arguments with default values.
Regards,
Máté
Hello internals,
I updated the RFC to encompass all the feedback:
https://wiki.php.net/rfc/deprecate-implicitly-nullable-types
Let me know if there are any final remarks before we start the vote sometime next week.
Best regards,
Gina P. Banyard