Hi everyone,
Since constructor property promotion is now implemented, and it looks
like it could become a widely used feature, I am proposing a small,
cosmetic change in syntax for constructors in concrete classes to do
away with empty constructor body.
Here's an example of how this would work:
<?php
namespace App;
class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}
Some notes to this:
- Since this is similar to already existing syntax for body-less
methods, parser should not be affected that much. I hope. I really have
no idea. - Syntax would be optional - meaning, you can as well continue using
empty body, just that in this case the body would be implied empty.
Thoughts?
Regards,
- Matīss
Hey Matīss,
This already works by replacing ;
with {}
: https://3v4l.org/tN4HM
Is the change in AST really necessary, considering that?
Marco Pivetta
Hi everyone,
Since constructor property promotion is now implemented, and it looks
like it could become a widely used feature, I am proposing a small,
cosmetic change in syntax for constructors in concrete classes to do
away with empty constructor body.Here's an example of how this would work:
<?php
namespace App;class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}Some notes to this:
- Since this is similar to already existing syntax for body-less
methods, parser should not be affected that much. I hope. I really have
no idea.- Syntax would be optional - meaning, you can as well continue using
empty body, just that in this case the body would be implied empty.Thoughts?
Regards,
- Matīss
Hi Marco,
I am not sure, that's why I am asking for feedback.
I have been converting a ton of code to use constructor property promotion
and the absolute majority ends up with the method body being empty. I
reckon this could be a nice eye-candy to have, however, it's nothing more
than that.
Another point to be made here, as far as my interpretation of PSR-12, the
curly braces occupy two lines for methods with multiline arguments. So for
whoever follows PSR-12, it's more like this, with brackets just dangling
there across 2 lines.
[...]
class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
) {
}
}
- Matīss
Hey Matīss,
This already works by replacing
;
with{}
: https://3v4l.org/tN4HMIs the change in AST really necessary, considering that?
Marco Pivetta
On Mon, May 10, 2021 at 10:29 AM Matīss Treinis mrtreinis@gmail.com
wrote:Hi everyone,
Since constructor property promotion is now implemented, and it looks
like it could become a widely used feature, I am proposing a small,
cosmetic change in syntax for constructors in concrete classes to do
away with empty constructor body.Here's an example of how this would work:
<?php
namespace App;class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}Some notes to this:
- Since this is similar to already existing syntax for body-less
methods, parser should not be affected that much. I hope. I really have
no idea.- Syntax would be optional - meaning, you can as well continue using
empty body, just that in this case the body would be implied empty.Thoughts?
Regards,
- Matīss
Hi Marco,
I am not sure, that's why I am asking for feedback.
I have been converting a ton of code to use constructor property promotion
and the absolute majority ends up with the method body being empty. I
reckon this could be a nice eye-candy to have, however, it's nothing more
than that.Another point to be made here, as far as my interpretation of PSR-12, the
curly braces occupy two lines for methods with multiline arguments. So for
whoever follows PSR-12, it's more like this, with brackets just dangling
there across 2 lines.[...]
class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
) {
}
}
Given that:
-
{}
can already represent what you want - the issue is more of a coding-style related topic
I suggest bringing this up in a new PSR instead. Consider that PSR-1, PSR-2
and PSR-12 were designed pre-PHP-8, so they will need adjustments again,
but AFAIK nothing has moved yet, since the ecosystem is still adapting to
the PHP 8 changes (I myself haven't finished adopting it on many of my
libraries).
If this is relevant to you right now, add an exclusion to your
phpcs.xml.dist
instead: easier and less painful than expanding the
language for such a tiny detail.
Marco Pivetta
I don't necessarily agree with this point in particular - I mentioned PSR
just-by-driveby, since whoever does follow that convention will face this
issue - but the scope of the proposal is not limited to PSR adopters. It's
also worth pointing out that PSR is not an "official" coding guideline for
PHP, and therefore we should probably not limit the scope to it, simply
because regardless if the brackets are on the same line or not, they are
still there.
IMO, this is a language issue - topical, cosmetic, and minor - but language
issue nevertheless, in fact, exactly like the one had for attribute syntax.
Let's gather some feedback and see.
- Matīss
On Mon, May 10, 2021 at 10:50 AM Matīss Treinis mrtreinis@gmail.com
wrote:Hi Marco,
I am not sure, that's why I am asking for feedback.
I have been converting a ton of code to use constructor property
promotion and the absolute majority ends up with the method body being
empty. I reckon this could be a nice eye-candy to have, however, it's
nothing more than that.Another point to be made here, as far as my interpretation of PSR-12, the
curly braces occupy two lines for methods with multiline arguments. So for
whoever follows PSR-12, it's more like this, with brackets just dangling
there across 2 lines.[...]
class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
) {
}
}Given that:
{}
can already represent what you want- the issue is more of a coding-style related topic
I suggest bringing this up in a new PSR instead. Consider that PSR-1,
PSR-2 and PSR-12 were designed pre-PHP-8, so they will need adjustments
again, but AFAIK nothing has moved yet, since the ecosystem is still
adapting to the PHP 8 changes (I myself haven't finished adopting it on
many of my libraries).If this is relevant to you right now, add an exclusion to your
phpcs.xml.dist
instead: easier and less painful than expanding the
language for such a tiny detail.Marco Pivetta
Hey Matīss
http://ocramius.github.com/
I don't necessarily agree with this point in particular - I mentioned PSR
just-by-driveby, since whoever does follow that convention will face this
issue - but the scope of the proposal is not limited to PSR adopters. It's
also worth pointing out that PSR is not an "official" coding guideline for
PHP, and therefore we should probably not limit the scope to it, simply
because regardless if the brackets are on the same line or not, they are
still there.IMO, this is a language issue - topical, cosmetic, and minor - but
language issue nevertheless, in fact, exactly like the one had for
attribute syntax.Let's gather some feedback and see.
At language level, {}
is pretty much "no body" - it's more of an
optimization pass for OpCache at that point.
Adding AST always comes with major complexity for all the ecosystem: since
there is AST isomorphic to the proposal, and it's literally one character
in difference, I don't see a clear advantage.
Marco Pivetta
Another point to be made here, as far as my interpretation of PSR-12, the
curly braces occupy two lines for methods with multiline arguments. So
for
whoever follows PSR-12, it's more like this, with brackets just dangling
there across 2 lines.Given that:
{}
can already represent what you want- the issue is more of a coding-style related topic
I suggest bringing this up in a new PSR instead. Consider that PSR-1, PSR-2
and PSR-12 were designed pre-PHP-8, so they will need adjustments again,
but AFAIK nothing has moved yet, since the ecosystem is still adapting to
the PHP 8 changes (I myself haven't finished adopting it on many of my
libraries).
A whole lot of agreeing with Marco here. The problem is the coding
standard, not the syntax.
Also, as Guilliam said in a later reply, using semicolon already has a
meaning and this contradicts that. Let's not make the syntax more
confusing purely to avoid updating a PSR that was meant to be a living
standard.
-Sara
Another point to be made here, as far as my interpretation of PSR-12, the
curly braces occupy two lines for methods with multiline arguments. So for
whoever follows PSR-12, it's more like this, with brackets just dangling
there across 2 lines.[...]
class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
) {
}
}
or some would prefer:
class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
) {
// empty
}
}
The question to the proposal. Will this new syntax apply to:
- all methods
- all constructors
- only to constructors with property promotion?
I think 3 makes most sense here and is less contentious. So, just be
sure to specify this in the RFC.
--
Aleksander Machniak
Kolab Groupware Developer [https://kolab.org]
Roundcube Webmail Developer [https://roundcube.net]
PGP: 19359DC1 # Blog: https://kolabian.wordpress.com
Hi internals
Hey Matīss,
This already works by replacing
;
with{}
: https://3v4l.org/tN4HMIs the change in AST really necessary, considering that?
The root problem is not that {} is significantly worse than ; but it's
that some cs tools require obnoxious formatting.
class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
) {
}
}
I agree with Marco, it makes more sense to fix the cs guidelines
rather than to adjust the language just to work around it.
Ilija
Hi everyone,
Since constructor property promotion is now implemented, and it looks
like it could become a widely used feature, I am proposing a small,
cosmetic change in syntax for constructors in concrete classes to do
away with empty constructor body.Here's an example of how this would work:
<?php
namespace App;class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}Some notes to this:
- Since this is similar to already existing syntax for body-less
methods, parser should not be affected that much. I hope. I really have
no idea.- Syntax would be optional - meaning, you can as well continue using
empty body, just that in this case the body would be implied empty.Thoughts?
Regards,
- Matīss
Hi,
To me ;
means not "empty body" (that's {}
) but really "no definition,
only declaration" (or "no body, only signature", and also "no code
executed"), i.e. an abstract method (either explicitly declared so in a
class, or implicitly in an interface).
Granted, property promotion is already special (cannot be used in an
abstract constructor), but it can also be mixed with non-promoted
parameters and body, so I feat that your proposed alternative syntax would
bring more confusion than convenience :s
Regards,
--
Guilliam Xavier
On Mon, May 10, 2021 at 6:31 AM Guilliam Xavier guilliam.xavier@gmail.com
wrote:
On Mon, May 10, 2021 at 10:29 AM Matīss Treinis mrtreinis@gmail.com
wrote:Hi everyone,
Since constructor property promotion is now implemented, and it looks
like it could become a widely used feature, I am proposing a small,
cosmetic change in syntax for constructors in concrete classes to do
away with empty constructor body.Here's an example of how this would work:
<?php
namespace App;class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}Some notes to this:
- Since this is similar to already existing syntax for body-less
methods, parser should not be affected that much. I hope. I really have
no idea.- Syntax would be optional - meaning, you can as well continue using
empty body, just that in this case the body would be implied empty.Thoughts?
Regards,
- Matīss
Hi,
To me
;
means not "empty body" (that's{}
) but really "no definition,
only declaration" (or "no body, only signature", and also "no code
executed"), i.e. an abstract method (either explicitly declared so in a
class, or implicitly in an interface).Granted, property promotion is already special (cannot be used in an
abstract constructor), but it can also be mixed with non-promoted
parameters and body, so I feat that your proposed alternative syntax would
bring more confusion than convenience :sRegards,
--
Guilliam Xavier
I'm ambivalent about this proposal, but figured I'd throw out one advantage
to ; over {}. In my opinion, ending with a semicolon is a very clear way of
saying there is no body to the method, while having {} could indicate that
implementation of the body was intended but never actually done. I know
that when I'm writing new classes I often will set up the method signature
but leave the method body empty while I finish the code that utilizes that
method. I don't know if that is justification for the proposal, but it is
one reason why ; might be preferred over {}.
--
Chase Peeler
chasepeeler@gmail.com
On Mon, May 10, 2021 at 6:31 AM Guilliam Xavier guilliam.xavier@gmail.com
wrote:On Mon, May 10, 2021 at 10:29 AM Matīss Treinis mrtreinis@gmail.com
wrote:Hi everyone,
Since constructor property promotion is now implemented, and it looks
like it could become a widely used feature, I am proposing a small,
cosmetic change in syntax for constructors in concrete classes to do
away with empty constructor body.Here's an example of how this would work:
<?php
namespace App;class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}Some notes to this:
- Since this is similar to already existing syntax for body-less
methods, parser should not be affected that much. I hope. I really have
no idea.- Syntax would be optional - meaning, you can as well continue using
empty body, just that in this case the body would be implied empty.Thoughts?
Regards,
- Matīss
Hi,
To me
;
means not "empty body" (that's{}
) but really "no definition,
only declaration" (or "no body, only signature", and also "no code
executed"), i.e. an abstract method (either explicitly declared so in a
class, or implicitly in an interface).Granted, property promotion is already special (cannot be used in an
abstract constructor), but it can also be mixed with non-promoted
parameters and body, so I feat that your proposed alternative syntax would
bring more confusion than convenience :sRegards,
--
Guilliam XavierI'm ambivalent about this proposal, but figured I'd throw out one advantage
to ; over {}. In my opinion, ending with a semicolon is a very clear way of
saying there is no body to the method, while having {} could indicate that
implementation of the body was intended but never actually done. I know
that when I'm writing new classes I often will set up the method signature
but leave the method body empty while I finish the code that utilizes that
method. I don't know if that is justification for the proposal, but it is
one reason why ; might be preferred over {}.--
Chase Peeler
chasepeeler@gmail.com
I agree that in the grand scheme of things this would be a minor matter, but aesthetically I would prefer it as well. The {} annoys me, CS tools or no.
Related: I feel the same way about empty-classes and interfaces, which is often the case for exceptions where all you're doing is declaring a type. I figure that would get even more pushback, though. :-)
As a data point, you can already do the same "semi-colon for no body" for foreach, for, and while loops. I've only ever done it on foreach to runout an iterator, but it works on all three today.
--Larry Garfield
If constructor is supposed to be empty then why are we even bothering with
construction promoting style? Why aren't we sticking to the old way of
defining properties?
Are there any advantages to using construction promoting style?
I mean sure we could have this:
class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}
but in my opinion, the old way of defining them is nice and concise:
class Foo {
private Bar $bar;
private Baz $baz;
}
What is the point of taking the hard way and then making it convenient?
On Mon, May 10, 2021 at 6:31 AM Guilliam Xavier <
guilliam.xavier@gmail.com>
wrote:On Mon, May 10, 2021 at 10:29 AM Matīss Treinis mrtreinis@gmail.com
wrote:Hi everyone,
Since constructor property promotion is now implemented, and it looks
like it could become a widely used feature, I am proposing a small,
cosmetic change in syntax for constructors in concrete classes to do
away with empty constructor body.Here's an example of how this would work:
<?php
namespace App;class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}Some notes to this:
- Since this is similar to already existing syntax for body-less
methods, parser should not be affected that much. I hope. I really
have
no idea.- Syntax would be optional - meaning, you can as well continue using
empty body, just that in this case the body would be implied empty.Thoughts?
Regards,
- Matīss
Hi,
To me
;
means not "empty body" (that's{}
) but really "no
definition,
only declaration" (or "no body, only signature", and also "no code
executed"), i.e. an abstract method (either explicitly declared so
in a
class, or implicitly in an interface).Granted, property promotion is already special (cannot be used in an
abstract constructor), but it can also be mixed with non-promoted
parameters and body, so I feat that your proposed alternative syntax
would
bring more confusion than convenience :sRegards,
--
Guilliam XavierI'm ambivalent about this proposal, but figured I'd throw out one
advantage
to ; over {}. In my opinion, ending with a semicolon is a very clear way
of
saying there is no body to the method, while having {} could indicate
that
implementation of the body was intended but never actually done. I know
that when I'm writing new classes I often will set up the method
signature
but leave the method body empty while I finish the code that utilizes
that
method. I don't know if that is justification for the proposal, but it is
one reason why ; might be preferred over {}.--
Chase Peeler
chasepeeler@gmail.comI agree that in the grand scheme of things this would be a minor matter,
but aesthetically I would prefer it as well. The {} annoys me, CS tools or
no.Related: I feel the same way about empty-classes and interfaces, which is
often the case for exceptions where all you're doing is declaring a type.
I figure that would get even more pushback, though. :-)As a data point, you can already do the same "semi-colon for no body" for
foreach, for, and while loops. I've only ever done it on foreach to runout
an iterator, but it works on all three today.--Larry Garfield
--
To unsubscribe, visit: https://www.php.net/unsub.php
If constructor is supposed to be empty then why are we even bothering with
construction promoting style? Why aren't we sticking to the old way of
defining properties?
Are there any advantages to using construction promoting style?I mean sure we could have this:
class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}but in my opinion, the old way of defining them is nice and concise:
class Foo {
private Bar $bar;
private Baz $baz;
}What is the point of taking the hard way and then making it convenient?
-
Please don't top-post.
-
The reason is that the old way doesn't provide any way to populate them on construction. The pattern of "assign the arg to the prop in the constructor" is stupendously common, and promotion makes it vastly more convenient.
For more details:
https://platform.sh/blog/2020/php-80-feature-focus-constructor-property-promotion/
The constructor isn't "supposed" to be empty. It just often is with promotion, because the constructor wasn't doing anything else besides shuffling its parameters over to properties, which is now automatic.
--Larry Garfield
Please don't top-post.
The reason is that the old way doesn't provide any way to populate them
on construction. The pattern of "assign the arg to the prop in the
constructor" is stupendously common, and promotion makes it vastly more
convenient.For more details:
https://platform.sh/blog/2020/php-80-feature-focus-constructor-property-promotion/
The constructor isn't "supposed" to be empty. It just often is with
promotion, because the constructor wasn't doing anything else besides
shuffling its parameters over to properties, which is now automatic.--Larry Garfield
Sorry for top-posting. Didn't know what it means :), also it was kind of my
first reply to mailing list.
Yes, I see now. I had forgotten that bit when I replied; apologies.
I guess it makes sense now to end the constructor with a semicolon when it
holds no body.
Hossein Baghayi wrote on 5/10/21 13:01:
- Please don't top-post.
Sorry for top-posting. Didn't know what it means :), also it was kind of my
first reply to mailing list.
https://github.com/php/php-src/blob/master/docs/mailinglist-rules.md
:-)
Cheers,
Ben
Le 10/05/2021 à 18:58, Larry Garfield a écrit :
I agree that in the grand scheme of things this would be a minor matter, but aesthetically I would prefer it as well. The {} annoys me, CS tools or no.
Related: I feel the same way about empty-classes and interfaces, which is often the case for exceptions where all you're doing is declaring a type. I figure that would get even more pushback, though. :-)
As a data point, you can already do the same "semi-colon for no body" for foreach, for, and while loops. I've only ever done it on foreach to runout an iterator, but it works on all three today.
--Larry Garfield
I didn't saw this answer at first, but I agree that:
interface MyLibraryException;
class DefaultMyLibraryException extends \RuntimeException implements
MyLibraryException;
Is an excellent use case for this!
Regards,
Pierre
Le 10/05/2021 à 18:58, Larry Garfield a écrit :
I agree that in the grand scheme of things this would be a minor matter,
but aesthetically I would prefer it as well. The {} annoys me, CS tools or
no.Related: I feel the same way about empty-classes and interfaces, which
is often the case for exceptions where all you're doing is declaring a
type. I figure that would get even more pushback, though. :-)As a data point, you can already do the same "semi-colon for no body"
for foreach, for, and while loops. I've only ever done it on foreach to
runout an iterator, but it works on all three today.--Larry Garfield
I didn't saw this answer at first, but I agree that:
interface MyLibraryException; class DefaultMyLibraryException extends \RuntimeException implements MyLibraryException;
Is an excellent use case for this!
I'm probably biased by my C++ background but to me this looks like "forward
declarations" (i.e. just declares types but doesn't define them) :/
Regards,
--
Guilliam Xavier
Hi everyone,
Since constructor property promotion is now implemented, and it looks
like it could become a widely used feature, I am proposing a small,
cosmetic change in syntax for constructors in concrete classes to do
away with empty constructor body.Here's an example of how this would work:
<?php
namespace App;class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}Some notes to this:
- Since this is similar to already existing syntax for body-less
methods, parser should not be affected that much. I hope. I really have
no idea.- Syntax would be optional - meaning, you can as well continue using
empty body, just that in this case the body would be implied empty.Thoughts?
Regards,
- Matīss
For what it's worth, I've received the same suggestion from quite a few
people. There seems to be an intuitive expectation that only adding a
semicolon will work in this case. Personally, I'm okay with allowing it.
If we allow it, I would restrict it to specifically the case of a) a
promoted constructor b) which has only promoted parameters. I don't think
we should allow replacing "{}" with ";" for methods in the general case.
Regards,
Nikita
Yes, just to clarify the scope of my initial proposal, this should only
ever apply to promoted constructors that have 1 or more promoted
parameters, and no not-promoted parameters.
These would NOT be considered valid:
public function __construct(
private Baz $baz,
Bar $bar
);
public function __construct();
public function __construct(Baz $baz);
as well as anything not related to __construct.
- Matīss
On Tue, May 11, 2021 at 10:58, Nikita Popov nikita.ppv@gmail.com
wrote:
On Mon, May 10, 2021 at 10:29 AM Matīss Treinis <mrtreinis@gmail.com
mailto:mrtreinis@gmail.com> wrote:Hi everyone,
Since constructor property promotion is now implemented, and it
looks
like it could become a widely used feature, I am proposing a small,
cosmetic change in syntax for constructors in concrete classes to do
away with empty constructor body.Here's an example of how this would work:
<?php
namespace App;class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}Some notes to this:
- Since this is similar to already existing syntax for body-less
methods, parser should not be affected that much. I hope. I really
have
no idea.- Syntax would be optional - meaning, you can as well continue using
empty body, just that in this case the body would be implied empty.Thoughts?
Regards,
- Matīss
For what it's worth, I've received the same suggestion from quite a
few people. There seems to be an intuitive expectation that only
adding a semicolon will work in this case. Personally, I'm okay with
allowing it.If we allow it, I would restrict it to specifically the case of a) a
promoted constructor b) which has only promoted parameters. I don't
think we should allow replacing "{}" with ";" for methods in the
general case.Regards,
Nikita
Yes, just to clarify the scope of my initial proposal, this should only
ever apply to promoted constructors that have 1 or more promoted
parameters, and no not-promoted parameters.These would NOT be considered valid:
public function __construct( private Baz $baz, Bar $bar ); public function __construct(); public function __construct(Baz $baz);
as well as anything not related to __construct.
- Matīss
I've put up a quick implementation for this:
https://github.com/php/php-src/pull/6972
As this seems somewhat controversial, I'm afraid this change will have to
go through the RFC process.
Nikita
On Mon, May 10, 2021 at 10:29 AM Matīss Treinis mrtreinis@gmail.com
wrote:Hi everyone,
Since constructor property promotion is now implemented, and it looks
like it could become a widely used feature, I am proposing a small,
cosmetic change in syntax for constructors in concrete classes to do
away with empty constructor body.Here's an example of how this would work:
<?php
namespace App;class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}Some notes to this:
- Since this is similar to already existing syntax for body-less
methods, parser should not be affected that much. I hope. I really have
no idea.- Syntax would be optional - meaning, you can as well continue using
empty body, just that in this case the body would be implied empty.Thoughts?
Regards,
- Matīss
For what it's worth, I've received the same suggestion from quite a few
people. There seems to be an intuitive expectation that only adding a
semicolon will work in this case. Personally, I'm okay with allowing it.If we allow it, I would restrict it to specifically the case of a) a
promoted constructor b) which has only promoted parameters. I don't think
we should allow replacing "{}" with ";" for methods in the general case.Regards,
Nikita
Oh absolutely, and many thanks for doing the code part, Nikita!
I would propose leaving this open for debate till, say, 15th of May here on
internals ML to gather more input.
If there are no super strong arguments on why this should not happen or go
to RFC, I will draft a RFC and from there, the usual process applies.
- Matīss
On Tue, May 11, 2021 at 12:17 PM Matīss Treinis mrtreinis@gmail.com
wrote:Yes, just to clarify the scope of my initial proposal, this should only
ever apply to promoted constructors that have 1 or more promoted
parameters, and no not-promoted parameters.These would NOT be considered valid:
public function __construct( private Baz $baz, Bar $bar ); public function __construct(); public function __construct(Baz $baz);
as well as anything not related to __construct.
- Matīss
I've put up a quick implementation for this:
https://github.com/php/php-src/pull/6972As this seems somewhat controversial, I'm afraid this change will have to
go through the RFC process.Nikita
On Mon, May 10, 2021 at 10:29 AM Matīss Treinis mrtreinis@gmail.com
wrote:Hi everyone,
Since constructor property promotion is now implemented, and it looks
like it could become a widely used feature, I am proposing a small,
cosmetic change in syntax for constructors in concrete classes to do
away with empty constructor body.Here's an example of how this would work:
<?php
namespace App;class Foo {
public function __construct(
private Bar $bar,
private Baz $baz
);
}Some notes to this:
- Since this is similar to already existing syntax for body-less
methods, parser should not be affected that much. I hope. I really have
no idea.- Syntax would be optional - meaning, you can as well continue using
empty body, just that in this case the body would be implied empty.Thoughts?
Regards,
- Matīss
For what it's worth, I've received the same suggestion from quite a few
people. There seems to be an intuitive expectation that only adding a
semicolon will work in this case. Personally, I'm okay with allowing it.If we allow it, I would restrict it to specifically the case of a) a
promoted constructor b) which has only promoted parameters. I don't think
we should allow replacing "{}" with ";" for methods in the general case.Regards,
Nikita
Yes, just to clarify the scope of my initial proposal, this should only
ever apply to promoted constructors that have 1 or more promoted
parameters, and no not-promoted parameters.
Hard disagree. While it's certainly silly/pointless to have a nil
constructor when there are non-promoted args present, I think that
deliberately making that mode special (read: inconsistent) is the wrong way
to go.
These would NOT be considered valid:
public function __construct();
For example, Niki's reply showed a place where that mode is perfectly
reasonable (singleton finals). If you must have this syntactic sugar, then
please make it consistent.
as well as anything not related to __construct.
I'd be willing to go along with inconsistency since once you allow syntax
you can't unallow it without pain. So while I don't love the tack, I'll
follow it if we do this feature. (which IMO we shouldn't).
If there are no super strong arguments on why this should not happen or go
to RFC, I will draft a RFC and from there, the usual process applies.
I think you've heard a number of strong arguments why it should not happen,
but I also think this deserves its chance to be fleshed out and voted on,
so by all means, do work the RFC.
-Sara
On Tue, May 11, 2021 at 5:18 AM Matīss Treinis mrtreinis@gmail.com
wrote:Yes, just to clarify the scope of my initial proposal, this should only
ever apply to promoted constructors that have 1 or more promoted
parameters, and no not-promoted parameters.Hard disagree. While it's certainly silly/pointless to have a nil
constructor when there are non-promoted args present, I think that
deliberately making that mode special (read: inconsistent) is the wrong way
to go.These would NOT be considered valid:
public function __construct();For example, Niki's reply showed a place where that mode is perfectly
reasonable (singleton finals). If you must have this syntactic sugar, then
please make it consistent.as well as anything not related to __construct.
I'd be willing to go along with inconsistency since once you allow syntax
you can't unallow it without pain. So while I don't love the tack, I'll
follow it if we do this feature. (which IMO we shouldn't).
I agree. I think making things inconsistent between constructors and other
methods is something that can be lived with - there are already other
things special about constructors that don't apply to other methods - but
we should at least allow consistency among constructors and allow the
trailing semicolon in all cases.
On Tue, May 11, 2021 at 8:59 AM Matīss Treinis mrtreinis@gmail.com
wrote:If there are no super strong arguments on why this should not happen or
go
to RFC, I will draft a RFC and from there, the usual process applies.I think you've heard a number of strong arguments why it should not happen,
but I also think this deserves its chance to be fleshed out and voted on,
so by all means, do work the RFC.-Sara
--
Chase Peeler
chasepeeler@gmail.com
Le 11/05/2021 à 16:39, Chase Peeler a écrit :
I agree. I think making things inconsistent between constructors and other
methods is something that can be lived with - there are already other
things special about constructors that don't apply to other methods - but
we should at least allow consistency among constructors and allow the
trailing semicolon in all cases.
As Sara stated, the example of the singleton final constructor is a good
one, but another one I could think about which applies to all methods
is when implementing an interface, you may want to keep some of the
implemented methods just empty.
Why not applying the semicolon syntax as well for all methods ? It
doesn't seem like bad idea to me, I often write empty methods when
implementing the null object pattern, or when I have partial
implementations for specific use case, or just when I don't need to
implement an abstract or interface method.
I'm all in for consistency between constructor and all methods and allow
the semicolon to replace any empty method body.
Regards,
Pierre
Hi Sara,
While it's certainly silly/pointless to have a nil constructor when
there are non-promoted args present, I think that deliberately making
that mode special (read: inconsistent) is the wrong way to go.
Sorry, but I don't follow - so you would prefer that this:
public function __construct();
be valid syntax as well, considering within the scope of the proposed?
Am I reading this right?
- Matīss
On Tue, May 11, 2021 at 5:18 AM Matīss Treinis <mrtreinis@gmail.com
mailto:mrtreinis@gmail.com> wrote:Yes, just to clarify the scope of my initial proposal, this should
only
ever apply to promoted constructors that have 1 or more promoted
parameters, and no not-promoted parameters.Hard disagree. While it's certainly silly/pointless to have a nil
constructor when there are non-promoted args present, I think that
deliberately making that mode special (read: inconsistent) is the
wrong way to go.These would NOT be considered valid:
public function __construct();For example, Niki's reply showed a place where that mode is perfectly
reasonable (singleton finals). If you must have this syntactic
sugar, then please make it consistent.as well as anything not related to __construct.
I'd be willing to go along with inconsistency since once you allow
syntax you can't unallow it without pain. So while I don't love the
tack, I'll follow it if we do this feature. (which IMO we shouldn't).On Tue, May 11, 2021 at 8:59 AM Matīss Treinis <mrtreinis@gmail.com
mailto:mrtreinis@gmail.com> wrote:If there are no super strong arguments on why this should not
happen or go
to RFC, I will draft a RFC and from there, the usual process
applies.I think you've heard a number of strong arguments why it should not
happen, but I also think this deserves its chance to be fleshed out
and voted on, so by all means, do work the RFC.-Sara
Hi Sara,
While it's certainly silly/pointless to have a nil constructor when
there are non-promoted args present, I think that deliberately making
that mode special (read: inconsistent) is the wrong way to go.Sorry, but I don't follow - so you would prefer that this:
public function __construct();
be valid syntax as well, considering within the scope of the proposed?
Am I reading this right?
Yes. It might be silly and pointless, but, it doesn't have any negative
side effects, so why not?
- Matīss
On Tue, May 11, 2021 at 5:18 AM Matīss Treinis <mrtreinis@gmail.com
mailto:mrtreinis@gmail.com> wrote:Yes, just to clarify the scope of my initial proposal, this should
only
ever apply to promoted constructors that have 1 or more promoted
parameters, and no not-promoted parameters.Hard disagree. While it's certainly silly/pointless to have a nil
constructor when there are non-promoted args present, I think that
deliberately making that mode special (read: inconsistent) is the
wrong way to go.These would NOT be considered valid:
public function __construct();For example, Niki's reply showed a place where that mode is perfectly
reasonable (singleton finals). If you must have this syntactic
sugar, then please make it consistent.as well as anything not related to __construct.
I'd be willing to go along with inconsistency since once you allow
syntax you can't unallow it without pain. So while I don't love the
tack, I'll follow it if we do this feature. (which IMO we shouldn't).On Tue, May 11, 2021 at 8:59 AM Matīss Treinis <mrtreinis@gmail.com
mailto:mrtreinis@gmail.com> wrote:If there are no super strong arguments on why this should not
happen or go
to RFC, I will draft a RFC and from there, the usual process
applies.I think you've heard a number of strong arguments why it should not
happen, but I also think this deserves its chance to be fleshed out
and voted on, so by all means, do work the RFC.-Sara
--
Chase Peeler
chasepeeler@gmail.com
Le 11/05/2021 à 16:50, Chase Peeler a écrit :
Hi Sara,
While it's certainly silly/pointless to have a nil constructor when
there are non-promoted args present, I think that deliberately making
that mode special (read: inconsistent) is the wrong way to go.Sorry, but I don't follow - so you would prefer that this:
public function __construct();
be valid syntax as well, considering within the scope of the proposed?
Am I reading this right?Yes. It might be silly and pointless, but, it doesn't have any negative
side effects, so why not?
I agree, even for all methods, if I can avoid the {} when I don't need it.
To go further, for any method that return void or a nullable type, it
would be a nice to have the semicolon syntax automatically returning
null or void when possible, for when implementing an interface method or
abstract method you actually don't need to implement.
Regards,
Pierre
If we allow it, I would restrict it to specifically the case of a) a
promoted constructor b) which has only promoted parameters. I don't think
we should allow replacing "{}" with ";" for methods in the general case.
It could also be useful when you want to make sure constructor is
not defined, e.g.
private final function __construct();
(often seen in singleton implementations).
--
Best regards,
Bruce Weirdan mailto:weirdan@gmail.com
Le Tue, 11 May 2021 10:58:57 +0200,
Nikita Popov nikita.ppv@gmail.com a écrit :
If we allow it, I would restrict it to specifically the case of a) a
promoted constructor b) which has only promoted parameters. I don't think
we should allow replacing "{}" with ";" for methods in the general case.
This would create a subtle difference of allowed syntax between a constructor
and an other method, and between a constructor with promoted parameters and
without. I think we should avoid this.
I even thought we merged changes to make constructors more like the other
methods, but I just checked and it seems the RFCs to allow ": void" on
constructors were declined.
Côme
On Tue, May 11, 2021 at 4:37 PM Côme Chilliet <
come.chilliet@fusiondirectory.org> wrote:
Le Tue, 11 May 2021 10:58:57 +0200,
Nikita Popov nikita.ppv@gmail.com a écrit :If we allow it, I would restrict it to specifically the case of a) a
promoted constructor b) which has only promoted parameters. I don't
think
we should allow replacing "{}" with ";" for methods in the general case.This would create a subtle difference of allowed syntax between a
constructor
and an other method, and between a constructor with promoted parameters
and
without. I think we should avoid this.I even thought we merged changes to make constructors more like the other
methods, but I just checked and it seems the RFCs to allow ": void" on
constructors were declined.
My thought here is that a constructor with (only) promoted properties is
hardly a constructor at all -- it's more like a special syntax for
declaring properties that happens to re-use the constructor notation,
because that allows it generalize in certain ways. It could have been
implemented with some other syntax that didn't explicitly mention
constructors at all, such as class Point($x, $y, $z) {} or something.
I don't think there's any particularly good reason to have a body-less
constructor outside the promotion case. The example given by Bruce
private final function __construct();
is going to throw a warning since PHP 8 -- while I lobbied against that
decision at the time, final private methods no longer have an effect, and
declaring such a constructor will buy you nothing apart from that warning.
If a body-less non-promoted constructor is used, the most likely assumption
would be that the programmer forgot an "abstract" modifier.
Is there some use-case for empty constructors that I'm missing here?
Regards,
Nikita
My thought here is that a constructor with (only) promoted properties is
hardly a constructor at all -- it's more like a special syntax for
declaring properties that happens to re-use the constructor notation,
because that allows it generalize in certain ways. It could have been
implemented with some other syntax that didn't explicitly mention
constructors at all, such as class Point($x, $y, $z) {} or something.
Agreed. I've personally been a little hesitant to start using CPP because
of this. Declare constructor parameters AND declare properties AND
magically provide a constructor implementation that sets their values. It
looks like a constructor, but it's actually a little different. For me,
this proposal would really help clear that up.
When I see a method with an empty body, I think "this method does have an
implementation, and that implementation does exactly nothing." In the case
of CPP, this isn't true. The method appears to do exactly nothing, but in
fact it has an automatically defined implementation that sets the
properties to the given values.
When I see a semi-colon-terminated method, I think "this method has no
implementation here; one will be provided from somewhere else." This is
the case in abstract classes and interfaces--the subclass provides the
implementation. And it's the case in CPP too--an implementation that sets
the properties to the given values is automatically provided. For this
reason, I don't see it as inconsistent. The semi-colon means someone else
will provide an implementation, and CPP does just that.
Regards,
--Matthew
My thought here is that a constructor with (only) promoted properties is
hardly a constructor at all -- it's more like a special syntax for
declaring properties that happens to re-use the constructor notation,
because that allows it generalize in certain ways. It could have been
implemented with some other syntax that didn't explicitly mention
constructors at all, such as class Point($x, $y, $z) {} or something.Agreed. I've personally been a little hesitant to start using CPP because
of this. Declare constructor parameters AND declare properties AND
magically provide a constructor implementation that sets their values. It
looks like a constructor, but it's actually a little different. For me,
this proposal would really help clear that up.When I see a method with an empty body, I think "this method does have an
implementation, and that implementation does exactly nothing." In the case
of CPP, this isn't true. The method appears to do exactly nothing, but in
fact it has an automatically defined implementation that sets the
properties to the given values.When I see a semi-colon-terminated method, I think "this method has no
implementation here; one will be provided from somewhere else." This is
the case in abstract classes and interfaces--the subclass provides the
implementation. And it's the case in CPP too--an implementation that sets
the properties to the given values is automatically provided. For this
reason, I don't see it as inconsistent. The semi-colon means someone else
will provide an implementation, and CPP does just that.
After you put it into these terms, this reminds me a lot of
https://wiki.php.net/rfc/property_accessors#implicit_implementation. For
accessors there's very much a difference between
public $prop { get; } // auto-generated get
and
public $prop { get {} } // explicit get that doesn't do anything
Making "allow replacing {} with ;" as a general feature would certainly
pose a problem for this choice of syntax (which is inspired by C#).
Regards,
Nikita