Re: [RFC] Primary Constructors
| From: | Larry Garfield | Date: | Mon, 29 Jun 2026 16:59:14 +0000 |
| Subject: | Re: [RFC] Primary Constructors | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-131592@lists.php.net to get a copy of this message | ||
On Sun, Jun 28, 2026, at 7:17 PM, Rob Landers wrote:
> Hello internals,
>
> I'd like to put forward Primary Constructors
> <https://wiki.php.net/rfc/primary-constructors> for
> comment.
>
> An implementation PR will be opened later today (UTC), and the RFC
> updated with this discussion thread.
>
> — Rob
I support this feature, and am glad to see it. It will make struct-objects that much easier to
write, as well as more interesting value objects.
To the objections about readonly... Seriously, readonly is broken. :-) Use private(set) instead and
you get essentially the same effect, unless you're doing something screwy inside your class.
And if you are, then you already know it.
As Rob already noted, there's a massive number of existing classes where it's not even an
issue: There's no hooks or need for them, and readonly works fine then. Or switching them over
to private(set) if adding a hook in the future is not hard. (Unless there's inheritance
involved, and then the problem is inheritance. :-) )
We can't remove readonly from the language, but we should not allow its limitations and flaws
to keep us from making our lives easier.
The RFC has no mention of attributes. An example of that would be helpful, even though I presume
it's exactly what one would expect it to be.
The one addition I would ask for is to note that in Kotlin and Swift, there is a
post-primary-constructor initializer, called an
init block. It has no body, but lets
you do post-property-assignment stuff. It's basically an argument-free constructor. I think
that would go a long way toward smoothing the concerns people have about this feature being too
"locked down."
If we don't want a new keyword for it, we could allow a __construct method that has NO
arguments if there is a primary constructor. It would get called last, after everything else
(including parent constructors if appropriate) has run. (Whether it's spelled
__construct() { ]] or __construct { }, I don't have a strong
opinion.) A __construct that does take arguments would still be a compile-time conflict with a
primary constructor.
--Larry Garfield