Re: Primary Constructors

From: 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) {
     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:
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

« previous php.internals (#131446) next »