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