Re: [RFC] Primary Constructors
| From: | Tim Düsterhus | Date: | Mon, 29 Jun 2026 20:27:33 +0000 |
| Subject: | Re: [RFC] Primary Constructors | ||
| References: | 1 2 3 4 5 6 7 8 9 10 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-131623@lists.php.net to get a copy of this message | ||
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.
The stated goal of the RFC (from the introduction) is: “removing […] boilerplate”. It specifically does so by allowing to omit `public function __construct“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.
, 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