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

Reply via email to