Re: Primary Constructors
| From: | Nick Sdot | Date: | Mon, 22 Jun 2026 07:27:46 +0000 |
| Subject: | Re: Primary Constructors | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-131446@lists.php.net to get a copy of this message | ||
On 18.06.26 04:32, Rob Landers wrote:
Hello internals, I was reminded of my records RFC today, and one of the features of the RFC was "short constructors" generally called "primary constructors" in C#/Kotlin. They would look like this: class Point(public int $x, int $id = 0) extends Base($id); Which is just sugar for this: class Point extends Base { public function __construct(public int $x, int $id = 0) {Hey Rob, I was excited about the Records RFC when I read it first. The "inline constructors" part was one of the things I loved the most about it. Glad to see you are picking it up as a stand-alone concept here! Having the constructor up there makes a lot of sense to me. Especially now with property hooks, that happen to move the constructor down in the file a lot -- because people are used to define properties before the constructor. Personally, I would love to see class construction to happen at the very top -- as proposed here. One thing I found weird about the "inline constructors" in the Records RFC was that it allowed primary (inline) *and* traditional constructors. Good to see that it is different in this proposal. However, I have one concern... Making this property hooks only has the downside that the classes cannot beparent::__construct($id);} } or this: class Point extends Base { public int $x; public function __construct(int $x, int $id = 0) {$this->x = $x; parent::__construct($id);} } A class with a primary constructor *may not* have a defined |__construct| function. Any special initialization must be done with hooks: class Temperature( public float $celsius {set { if ($value < -273.15) { throw new ValueError('below absolute zero'); } $this->celsius = $value; }} ) {} new Temperature(20.0); // ok new Temperature(-300.0); // ValueError: below absolute zero I'm sending this email to the list to gather additional feedback before pursuing a formal RFC proposal. — Rob
readonly.
Which makes it unusable in many situations where it would be neat to use primary constructors.
I already back then wanted to propose the following, to avoid having two constructor types, but I think it also makes sense here because of the readonly-issue:
readonly class Point(public int $x, int $id = 0) => { // still allows hooks without readonly
// normal constructor body behaviour
} extends Base($id) {
// class body
}
Same as in your proposal it's just sugar. I'd expect it to behave the exact same as a normal __construct body, and the => {} to be optional.
As mentioned above, the sole benefit for me would be to have class construction at the very top, co-located with the class definition itself.
You open a class -> you know what it consumes, and how it is constructed. Would be awesome!
Would you be open to something like this?
--
Cheers
Nick