On Thu, Jul 18, 2024, at 10:11 AM, Oliver Nybroe wrote:
> Thanks for sharing previous discussions, I will definitely take a look 
> at those before writing up the RFC. 
>
>
>> If you do with to go with an RFC, I'd like to see if your proposal
> addresses whether this syntax should implicitly call
> `parent::__construct()`, and if a semi colon is expected or not
> (`public function __construct(public int $foo);` vs `public function
> __construct(public int $foo)`).
> Thank you, these are very valuable points to address in the RFC. 
>
> I can definitely feel that there will be some mixed opinions about 
> semicolon vs no semi colon.
>
>
> Best regards
> Oliver Nybroe (he/him)

Please don't top-post.

Since the last time this came up, PSR-12 has been replaced with PER-CS, which 
as of 2.0 now says: 

> If a function or method contains no statements or comments (such as an empty 
> no-op implementation or when using constructor property promotion), then the 
> body SHOULD be abbreviated as {} and placed on the same line as the previous 
> symbol, separated by a space.

cf: https://www.php-fig.org/per/coding-style/#44-methods-and-functions

(I... suppose technically it doesn't mention classes, but I've been doing it 
for empty classes too.)

So the "coding style" part of the previous issue has been resolved.  Whether 
that changes anyone's mind about whether this should be done or not is up to 
them to decide.

Personally, I'd probably vote for it if it came up, but I agree it's a pretty 
minor improvement and unlikely to pass.  It would probably only be worth doing 
if there were other common-pattern-optimizations around the constructor that 
came with it.  Things like auto-forwarding to the parent, or a more compact 
syntax than a full constructor method, or other things that make writing a 
"pure data" product type easier rather than just s/{}/;/

I don't know what those could look like.  As a data point, in Kotlin (which is 
what my day job is now), constructor properties are always promoted, 
essentially.  

class Foo(val a: String, val b: String) { // This is the equivalent of PHP's 
promoted properties.

  val c: Int = 5 // A non-constructor-initialized property. These can have 
hooks, constructor ones I think cannot.

  init {
    // This is the non-promoted part of a constructor body, and runs after the 
properties are assigned.
  }
}

In case of inheritance, there's dedicated required syntax for forwarding to the 
parent:


class Foo(val a: String, val b: String) : Bar(b) { // equivalent to 
parent::__construct($b)

}

You can also make the constructor private (etc.) with more explicitness:

class Foo private constructor(val a: String, val b: String) {}

Of note, if there's no constructor then the parens are omitted, and if there's 
no body then the {} body is omitted.  That means a great many "value 
objects"/DTOs, etc just look like this:

class Foo(
  val a: String,
  val b: String,
)

Which would be equivalent to PHP's

class Foo {
  public function __construct(
    public readonly string $a,
    public readonly string $b.
  ) {}
}

cf: https://kotlinlang.org/docs/classes.html

To be clear, I'm not suggesting PHP just copy Kotlin directly.  I'm saying that 
if we want to improve the constructor syntax for common cases, which I am open 
to, we should be looking to do something more substantial and ergonomic than 
just replacing {} with ;, and we could probably get some good inspiration from 
other languages in our family.  (Java, Kotlin, C#, Swift, etc.)

--Larry Garfield

Reply via email to