I'm looking for initial feedback on the following proposal.
Often, we have the following (fluent interface) setter method:
public function setName(?string $name): static
{
$this->name = $name;
return $this;
}
I propose to add "$this" as a return type, ie:
public function setName(?string $name): $this
{
$this->name = $name;
// implicit return $this;
}
public function setName(?string $name): $this
{
$this->name = $name;
// this would be an (compiler?) error
return $somethingOtherThanThis;
}
public function setName(?string $name): $this
{
$this->name = $name;
$self = $this;
// this would not be an error
return $self;
}
public function setName(?string $name): $this
{
$this->name = $name;
// technically useless, but not an error
return $this;
}
public function setName(?string $name): $this
{
$this->name = $name;
if ('foobar' === $name) {
// not an error to return early
return;
}
// do some other stuff
// any of the above legal examples
}
It should be obvious, but functions outside of a class context would not be
able to use this syntax.
BC:
There would be no BC breaks, as this syntax is currently invalid (Parse
error: syntax error, unexpected variable "$this").
Other Considerations:
With regards to reflection and inheritance, "$this" would be considered an
alias for "static".
Regards,
radar3301
I'm looking for initial feedback on the following proposal.
Often, we have the following (fluent interface) setter method:
public function setName(?string $name): static
{
$this->name = $name;return $this;
}
I propose to add "$this" as a return type, ie:
public function setName(?string $name): $this
{
$this->name = $name;
// implicit return $this;
}public function setName(?string $name): $this
{
$this->name = $name;
// this would be an (compiler?) error
return $somethingOtherThanThis;
}public function setName(?string $name): $this
{
$this->name = $name;
$self = $this;
// this would not be an error
return $self;
}public function setName(?string $name): $this
{
$this->name = $name;
// technically useless, but not an error
return $this;
}public function setName(?string $name): $this
{
$this->name = $name;
if ('foobar' === $name) {
// not an error to return early
return;
}
// do some other stuff// any of the above legal examples
}
It should be obvious, but functions outside of a class context would not
be able to use this syntax.BC:
There would be no BC breaks, as this syntax is currently invalid (Parse
error: syntax error, unexpected variable "$this").Other Considerations:
With regards to reflection and inheritance, "$this" would be considered an
alias for "static".Regards,
radar3301
I strongly agree that an alias for the "static" keyword is really necessary
to improve the semantics of the language.
The word "static" is used for many things: static methods, static classes
and Late Static Bindings (that is the case that you are discussing).
I think that in the case of Late Static Bindings (e.g. new static()
or
return type ..(): static
), the word "static" does not give any clue about
the meaning of that code.
Thus, I like your proposal.
The part that I do not like is the implicit return: it may confuse
developers and static analysis tools.
Is it possible to replace "$this" with "this"? Cleaner and coherent with
"self".
Regards,
Luigi
On Tue, Jun 25, 2024 at 9:51 AM Luigi Cardamone cardamoneluigi@gmail.com
wrote:
Is it possible to replace "$this" with "this"? Cleaner and coherent with
"self".
That wouldn't be possible, as this
is a valid class name:
https://3v4l.org/ujGOT
--
Best regards,
Bruce Weirdan mailto:
weirdan@gmail.com
I'm looking for initial feedback on the following proposal.
I propose to add "$this" as a return type, ie:
Worth reading:
- the previous RFC that didn't got to a voting stage:
https://wiki.php.net/rfc/this_return_type - the discussion thread: https://externals.io/message/115986
@Alexandru:
Worth reading:
Ah shoot, my search-fu failed me (it's not listed on the RFC page, and
I suppose I was not using
the right search terms). I'm glad to find out this rfc previously
existed, and in that case, I
guess I'd like to revive that discussion. :)
@Luigi:
The part that I do not like is the implicit return: it may confuse developers and static analysis
tools.
I understand the implicit return may be somewhat confusing, but one of
the secondary driving
factors, aside from a much clearer API signature (without requiring a
docblock comment), and engine
enforced object safety, was the benefit of reduced "boilerplate" code.
However, I suppose I can
accept that this may not be possible, but I would like to discuss it
as a potential option. However,
I disagree with you about the static analysis tools.
Is it possible to replace "$this" with "this"? Cleaner and coherent with "self".
I actually thought about this a bit before posting, and I came to the
same conclusion as Nicolas,
i.e.:
/**
- @return $this
*/
To quote Nicolas:
About the syntax, I think the one proposed in the RFC is crystal clear. I've been used to seeing
the "$" symbol [snip]
@previous commenters on the old thread
Andreas Heigl said:
If we allow a $this [snip] as a returntype to clarify that it has to be the same instance that is
returned, I would also either expect that the returntype 'self' does explicitly not allow the
same instance to be returned. As that would be a huge BC break [snip] we should implement a
returntype "!$this" to explicitly state that the contract here returns not the current instance
but a new one.
Strongly disagree. This would be too much of a BC, and I don't really
see the benefit, even allowing
for a "!$this"-style returntype. I'm not opposed to a separate RFC or
discussion regarding this, but
I don't feel it's appropriate here.
Sebastian Bergmann said:
[snip] please not "$this" as the name for a type.
Off the top of my head, I think that "same" could make sense.
My primary vote would still be for "$this" as explained above, but I
could potentially be persuaded
to switch to "this" or "same" as alternatives if the dollar-sign is
too much of a hang-up.
Regards,
radar3301
Sebastian Bergmann said:
[snip] please not "$this" as the name for a type.
Off the top of my head, I think that "same" could make sense.
My primary vote would still be for "$this" as explained above, but I
could potentially be persuaded
to switch to "this" or "same" as alternatives if the dollar-sign is
too much of a hang-up.
Not a fan of using a variable as a return type. This will cause havoc
for Tokenizer based static analysis tooling.
Not a fan of the implicit return either.
Also don't really see the need as there is the static
return type already.
On Tue, 25 Jun 2024 at 23:25, Juliette Reinders Folmer <
php-internals_nospam@adviesenzo.nl> wrote:
Also don't really see the need as there is the
static
return type
already.
I'd see it as useful if the type conveyed identity too, although it also
means that I would never use it, since I design immutable APIs, when
possible :D
Marco Pivetta
Juliette Reinders Folmer said:
Not a fan of using a variable as a return type. This will cause
havoc for Tokenizer based static analysis tooling.
I will concede that until the tools are updated to handle the new
(currently invalid) syntax, it would cause issues. But that happens
everytime a new syntax is introduced into PHP anyway (the original
return-types RFC, match, the proposed property accessors, etc.), so
I'm a bit confused as why this is an issue that would stop the RFC?
Juliette Reinders Folmer said:
Also don't really see the need as there is the
static
return type
already.
To quote Nicolas, who said it far better than I could:
I tried switching from the
@return $this
annotation to
function (): static
, which is the closest approximation currently
supported by the engine, when I realized that this would loosen the
semantics of the corresponding interfaces[.]
Marco Pivetta said:
I'd see it as useful if the type conveyed identity too, although it
means that I would never use it, since I design immutable APIs, when
possible :D
If reading documentation, I'd argue that seeing function(): $this
in
a class already conveys plenty of "identity". If you're talking about
using the Reflection API to get identity the original RFC by Nikita
stated:
The
$this
type is a subtype ofstatic
. As such, it is possible
to restrict astatic
type to$this
in a subclass (but not the
other way around).
In reflection, the$this
type is represented as a
ReflectionNamedType
withisBuiltin() == true
and
getName() == "$this"
.
So perhaps a change is needed in the returned ReflectionNamedType
to
better identity the actual class of $this
? Or am I missing your
point about identity here?
Bruce Weirdan said:
Luigi Cardamone wrote:
Is it possible to replace "$this" with "this"? Cleaner and coherent
with "self".That wouldn't be possible, as
this
is a valid class name:
The "Return Type Declarations", "Scalar Type Declarations", "Reserve
More Types", and "Void Return Type" RFCs all prohibited their usage as
class, interface and trait names. Using this
or same
or whatever
else is decided is just par for the course.
However, that said, a search of github for:
-
language:php "class This "
returns 5.1k results
(but it appears that most results are docblock comments) -
language:php "class This extends"
returns 27 results -
language:php "class This implements"
returns 8 results -
language:php "class Same "
returns 290 results -
language:php "class Same extends"
returns 193 results -
language:php "class Same implements"
returns 14 results -
language:php "@return $this"
returns 485k results.
Regards,
radar3301