Re: [PHP-DEV] [RFC] Primary Constructors

[email protected] (Tim Düsterhus)
Newsgroups php.internals
Message-ID <[email protected]>
Hi

Am 2026-06-29 22:06, schrieb Nick Sdot:
> ```
> 
> final readonly class Foo(Collection|array $value) implementsBar {
>     $this->items = $value instanceof Collection ? $value : new 
> Collection($value);
> }=> {
>     // class body private Collection $items
> 
> }
> 
> ```
> 
> How is this not easy to reason about? How is this not *less* confusing?

By introducing `=> {` as a new syntactical pattern that we don't 
currently have and where we would need to figure out whether that 
pattern would be consistent with existing use of `=>`. My gut feeling is 
“it isn’t”.

I'm also noting that your example doesn't declare the `$items` property, 
which to me is an indicator that it actually isn't that easy to reason 
about.

>> “Reduce typing” alone is not a sufficiently strong argument in favor 
>> of a new feature.
> 
> Not sure how reduce typing is related to the argument I am making? My 
> point is that I *want* primary constructors, but that they should allow 
> bodies to have the same workarounds at hand to deal with readonly and 
> hook issues as with conventional constructors.

The stated goal of the RFC (from the introduction) is: “removing […] 
boilerplate”. It specifically does so by allowing to omit `public 
function __construct`, `parent::__construct`, and a pair of braces. 
Personally I don't see much value in “just avoid typing some 
characters”. However for “logic-less” classes that just store some 
values, I can see where the proposal is coming from and the guarantee 
that the constructor actually is “logic-less” is some - small - benefit 
over “avoid typing characters that your IDE will autocomplete”.

This small benefit would entirely go away by allowing arbitrary logic in 
the constructor - and then as you said we would “[…] need to find an 
agreement on how parent constructor stuff works”, which is adding 
*extra* semantics that folks need to learn onto a feature that is 
supposed to make things *simpler*.

Staying with your example above, but declaring `$items`, I've come up 
with the following:

     final readonly class Foo(Collection|array $value) implements Bar {
         $this->items = $value instanceof Collection ? $value : new 
Collection($value);
     } => {
         public Collection $items;

         // class body private Collection $items
     }

     final readonly class Foo implements Bar {
         public Collection $items;

         public function __construct(Collection|array $value) {
             $this->items = $value instanceof Collection ? $value : new 
Collection($value);
         }

         // class body private Collection $items
     }

I find the latter *much* clearer.

Best regards
Tim Düsterhus
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.