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
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
Hey Rob,
thanks again for the work you did put into this!
Unfortunately you are not allowing bodies for primary constructor. This
means there will be no way to work around the "readonly classes don't
allow property hooks" problematic; except using conventional
constructors (private(set) is not the same; hence my previous
"readonly hooks" RFC).
If "use conventional constructors, if you need readonly classes"
stands, then the same can be argued for everything else in the RFC.
Why would we introduce a whole new syntax, but then only make it work
for limited use-cases such as "trivial validation or normalization"?
Your example:
class Money(
public readonly int$amount,
public readonly string$currency = 'USD',
) {}
class Money{
public function __construct(
public readonly int$amount,
public readonly string$currency = 'USD',
) {}
}
Pro:
- two lines less
- construction at top of class (love it!)
Con:
- primary constructor body not supported
- new syntax with gotchas to keep in mind
- for readonly classes it adds two property
readonlyin exchange to
writing two lines less - requires refactoring to conventional constructor as soon as it gets
"non-trivial" (I'd argue a lot of things that do not work are actually
still trivial).
Given the limitations, is this alone adding enough value? What is the
actual gain?
Adding a new syntax to the language but then lock it down as proposed
here does not feel right.
As is, I feel the proposal is too thin, it would unfortunately be yet
another feature that feels mid, incomplete, and introduces new gotchas.
Sorry, IMO, not worth it.
If we would say we want new and neat syntax sugar to write constructors
at the top of the class, I am all for it!
But then they would need to work like actual constructors (otherwise
it's not just sugar), without accepting yet another set of limitations
and weirdness's in a different place.
What I roughly have in mind:
readonly class Point(public int $x, int $id = 0) extends Base($id)
implements Foo {
// normal constructor body behaviour
} => {
// class body
}
--
Cheers
Nick
If "use conventional constructors, if you need
readonlyclasses"
stands, then the same can be argued for everything else in the RFC.
For the record, my view is completely the opposite: if the new syntax
allows everything a normal constructor does, just in a slightly
different position, it will lead to endless style discussions of which
to use.
In fact, I don't think even property hooks belong in a primary
constructor; they're ugly enough in a constructor promoted property.
I think it's perfectly fine to have short-hands that only cover specific
use cases, and longer forms that let you express more complex use
cases. It's one of the reasons I voted against the recent RFC to allow
an extra reassignment of properties in the constructor
[https://wiki.php.net/rfc/promoted_readonly_constructor_reassign].
--
Rowan Tommins
[IMSoP]
Hey Rowan,
If "use conventional constructors, if you need
readonlyclasses"
stands, then the same can be argued for everything else in the RFC.For the record, my view is completely the opposite: if the new syntax
allows everything a normal constructor does, just in a slightly
different position, it will lead to endless style discussions of which
to use.
That's a fair opinion, and not unexpected. Personally, I oppose
introducing more inconsistencies to PHP. Looks like that we need to have
these discussions then?
In fact, I don't think even property hooks belong in a primary
constructor; they're ugly enough in a constructor promoted property.
It's a feature that was accepted to PHP and exists already. So it
doesn't really matter whether we (I agree -- shouldn't be used for
anything more than eg a neat callback) find it ugly and we have to deal
with its existence. You are basically making a point for allowing
primary constructor bodies. Having them allows to have a readonly
classes with primary constructors, and assign properties in their body.
Neat.
I think it's perfectly fine to have short-hands that only cover
specific use cases, and longer forms that let you express more complex
use cases. It's one of the reasons I voted against the recent RFC to
allow an extra reassignment of properties in the constructor
[https://wiki.php.net/rfc/promoted_readonly_constructor_reassign].
For the record, my view is completely the opposite: without allowing
primary constructor bodies the added value of adding the new syntax is
nearly non-existent.
Quoting from your message in the first thread to this:
I don't think we should add extra syntax to the language just to
change people's habits. If you want a constructor body as the first
thing in the class, you can do that right now.
...because the exact argument can be made from either point of view. To
quote you again: "all or nothing"; bodies should be allowed.
--
Cheers
Nick