[RFC][Draft] Body-less __construct

php.internals

Matīss Roberts Treinis

5 years ago
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

Marco Pivetta

5 years ago
Hey Matīss, This already works by replacing `;` with `{}`: https://3v4l.org/tN4HM Is the change in AST really necessary, considering that? Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/ On Mon, May 10, 2021 at 10:29 AM Matīss Treinis <mrtreinis@gmail.com> wrote:

Matīss Roberts Treinis

5 years ago
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 On Mon, May 10, 2021 at 10:31 AM Marco Pivetta <ocramius@gmail.com> wrote:

Marco Pivetta

5 years ago
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 http://twitter.com/Ocramius http://ocramius.github.com/

Matīss Roberts Treinis

5 years ago
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:55 AM Marco Pivetta <ocramius@gmail.com> wrote:

Marco Pivetta

5 years ago
Hey Matīss <http://ocramius.github.com/> On Mon, May 10, 2021 at 11:12 AM Matīss Treinis <mrtreinis@gmail.com> wrote:
> 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 http://twitter.com/Ocramius http://ocramius.github.com/

Sara Golemon

5 years ago
On Mon, May 10, 2021 at 3:56 AM Marco Pivetta <ocramius@gmail.com> wrote:
> > 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

A.L.E.C

5 years ago
On 10.05.2021 10:49, Matīss Treinis wrote:
> 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: 1. all methods 2. all constructors 3. 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

Ilija Tovilo

5 years ago
Hi internals On Mon, May 10, 2021 at 10:32 AM Marco Pivetta <ocramius@gmail.com> wrote:
> > Hey Matīss, > > This already works by replacing `;` with `{}`: https://3v4l.org/tN4HM > > Is 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

Guilliam Xavier

5 years ago
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 :s Regards,
-- Guilliam Xavier

Chase Peeler

5 years ago
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 :s > > Regards, > > -- > 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

Larry Garfield

5 years ago
On Mon, May 10, 2021, at 9:40 AM, Chase Peeler wrote:
> 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 :s > > > > Regards, > > > > -- > > 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
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

Hossein Baghayi

5 years ago
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, 10 May 2021 at 21:28, Larry Garfield <larry@garfieldtech.com> wrote:

Larry Garfield

5 years ago
On Mon, May 10, 2021, at 12:16 PM, Hossein Baghayi wrote:
> 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?
1) Please don't top-post. 2) 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

Hossein Baghayi

5 years ago
On Mon, 10 May 2021 at 21:59, Larry Garfield <larry@garfieldtech.com> wrote:
> 1) Please don't top-post. > > 2) 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.

Ben Ramsey

5 years ago
Hossein Baghayi wrote on 5/10/21 13:01:
> On Mon, 10 May 2021 at 21:59, Larry Garfield <larry@garfieldtech.com> wrote: > >> 1) 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

Pierre

5 years ago
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

Guilliam Xavier

5 years ago
On Tue, May 11, 2021 at 5:07 PM Pierre <pierre-php@processus.org> wrote:
> 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

Nikita Popov

5 years ago
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

Matīss Roberts Treinis

5 years ago
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:

Nikita Popov

5 years ago
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/6972 As this seems somewhat controversial, I'm afraid this change will have to go through the RFC process. Nikita

Matīss Roberts Treinis

5 years ago
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:41 PM Nikita Popov <nikita.ppv@gmail.com> wrote:

Sara Golemon

5 years ago
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). 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

5 years ago
On Tue, May 11, 2021 at 10:34 AM Sara Golemon <pollita@php.net> wrote:
> 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

Pierre

5 years ago
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

Matīss Roberts Treinis

5 years ago
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 09:33, Sara Golemon <pollita@php.net> wrote:

Chase Peeler

5 years ago
On Tue, May 11, 2021 at 10:48 AM Matīss Treinis <mrtreinis@gmail.com> wrote:
> 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 09:33, Sara Golemon <pollita@php.net> wrote: > > 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

Pierre

5 years ago
Le 11/05/2021 à 16:50, Chase Peeler a écrit :
> On Tue, May 11, 2021 at 10:48 AM Matīss Treinis <mrtreinis@gmail.com> wrote: > >> 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

Weirdan

5 years ago
> 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

Côme Chilliet

5 years ago
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

Nikita Popov

5 years ago
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

Matthew Fonda

5 years ago
On Tue, May 11, 2021 at 7:45 AM Nikita Popov <nikita.ppv@gmail.com> wrote:
> 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

Nikita Popov

5 years ago
On Tue, May 11, 2021 at 6:56 PM Matt Fonda <matthewfonda@gmail.com> wrote:
> On Tue, May 11, 2021 at 7:45 AM Nikita Popov <nikita.ppv@gmail.com> wrote: > >> 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