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) {
parent::__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
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
be `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:
```php
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