Hi internals,
I would like to propose the following RFC, which allows using "static" as a
return type:
https://wiki.php.net/rfc/static_return_type
While I'm personally not a fan of late static binding, we do support it and
people do use it quite heavily, so I think we should also support it in
return types.
Regards,
Nikita
I would like to propose the following RFC, which allows using "static" as a
return type:https://wiki.php.net/rfc/static_return_type
While I'm personally not a fan of late static binding, we do support it and
people do use it quite heavily, so I think we should also support it in
return types.
A big +1 from me; I'd probably have assumed it would work and be
disappointed when it didn't.
I can see why late static binding isn't to everyone's taste as a concept,
but it is very useful to emulate other features like named constructors, as
you show in the RFC.
The fluent interface example is interesting, because it doesn't actually
involve late static binding at all, we just need some way to say "what
comes out is the same type as what goes in".
Regards,
Rowan Tommins
[IMSoP]
Hi internals,
I would like to propose the following RFC, which allows using "static" as a
return type:
So many "@return $this" docblocks are going to be deleted as a result of
this when PHP8 lands.
+1 from me.
--
Mark Randall
marandall@php.net
Hi internals,
I would like to propose the following RFC, which allows using "static" as a
return type:
Very happy to see this.
--
Paul M. Jones
pmjones@pmjones.io
http://paul-m-jones.com
Modernizing Legacy Applications in PHP
https://leanpub.com/mlaphp
Solving the N+1 Problem in PHP
https://leanpub.com/sn1php
I would like to propose the following RFC, which allows using "static" as a
return type:
https://wiki.php.net/rfc/static_return_type
Big +1 from me as well. I actually asked why this wasn't supported back in
2015:
static return type in PHP 7 interfaces
https://stackoverflow.com/q/30952876/759866
— Benjamin
Hi internals,
I would like to propose the following RFC, which allows using "static" as a
return type:https://wiki.php.net/rfc/static_return_type
While I'm personally not a fan of late static binding, we do support it and
people do use it quite heavily, so I think we should also support it in
return types.Regards,
Nikita
Yes, please!
For the fluent method example above, many projects will use a @return $this
annotation, rather than @return static.
In my own code, I usually use self
to mean “return the same instance.” While I know that, in practice, the use of self
is identical to using the class name as the return type, it seems natural to designate as practice (among my team) that self
always means itself and should never refer to an instance with different identity.
-Ben
Hi internals,
I would like to propose the following RFC, which allows using "static" as a
return type:https://wiki.php.net/rfc/static_return_type
While I'm personally not a fan of late static binding, we do support it and
people do use it quite heavily, so I think we should also support it in
return types.Regards,
Nikita
Is "squee!" an appropriate response on the list? For interface authors this is a huge deal.
--Larry Garfield
However, $this is not a real type, and it is unclear what the advantage
of specifying $this rather than static would be from a type system level
perspective.
Perhaps not from a "type system level", but from a more broad "enforced
contract" level.
E.g. IDEs or code inspection tools can warn if a method will not return
$this.
This also means recursive calls also need to return $this instead of static.
class C {
function foo(): static {
return clone $this;
}
function bar(): $this {
return $this->foo(); // IDE can complain.
}
}
Hi internals,
I would like to propose the following RFC, which allows using "static"
as a
return type:https://wiki.php.net/rfc/static_return_type
While I'm personally not a fan of late static binding, we do support it
and
people do use it quite heavily, so I think we should also support it in
return types.Regards,
NikitaIs "squee!" an appropriate response on the list? For interface authors
this is a huge deal.--Larry Garfield
However, $this is not a real type, and it is unclear what the advantage
of specifying $this rather than static would be from a type system level
perspective.Perhaps not from a "type system level", but from a more broad "enforced
contract" level.
E.g. IDEs or code inspection tools can warn if a method will not return
$this.
This also means recursive calls also need to return $this instead of
static.
class C {
function foo(): static {
return clone $this;
}
function bar(): $this {
return $this->foo(); // IDE can complain.
}
}
Of course this ": $this" could be added later in the future.
But this would have the risk that people start adding ": static" on methods
that really return $this.
This would cause confusion if later some packages introduce ": $this", but
others are still behind.
namespace oldpackage;
class B {
function foo(): static { // Actually returns $this, not just static.
return $this;
}
}
namespace newpackage;
class C extends B {
function foo(): $this {
return parent::foo(); // Should the IDE complain?
}
}
On Thu, 9 Jan 2020 at 15:07, Larry Garfield larry@garfieldtech.com
wrote:Hi internals,
I would like to propose the following RFC, which allows using "static"
as a
return type:https://wiki.php.net/rfc/static_return_type
While I'm personally not a fan of late static binding, we do support it
and
people do use it quite heavily, so I think we should also support it in
return types.Regards,
NikitaIs "squee!" an appropriate response on the list? For interface authors
this is a huge deal.--Larry Garfield
Of course this ": $this" could be added later in the future.
But this would have the risk that people start adding ": static" on methods
that really return $this.
I second $this. I also would like to be able to declare function foo(): $this
at the same time as function foo(): static
so that we can use the
most accurate description right away.
Although I'm not into the C part of the proposal, if I may have a
suggestion here, it would be to implement the check at compile time. Like
nullable return types check at compile time that return null;
is used
instead of just return;
, I think a $this
return type could and should
enforce return $this;
on all return point of such methods. That would
also make the check free at runtime.
Cheers,
Nicolas
However, $this is not a real type, and it is unclear what the advantage
of specifying $this rather than static would be from a type system level
perspective.Perhaps not from a "type system level", but from a more broad "enforced
contract" level.
E.g. IDEs or code inspection tools can warn if a method will not return
$this.
This also means recursive calls also need to return $this instead of
static.class C {
function foo(): static {
return clone $this;
}
function bar(): $this {
return $this->foo(); // IDE can complain.
}
}
I think there are two different purposes for annotating return types:
- Contracts that tell the caller what values they should expect when
calling the function. - Constraints on the implementation which don't affect the caller, but
allow the author to catch certain bugs.
The primary purpose, in my mind, is (1), with (2) generally coming as a
side-effect: if your contract is to return an int, then tools can warn you
when you don't.
All concrete types can be seen this way: scalars, classes, and pseudo-types
like "iterable" are all contracts that calling code can rely on. "self",
"parent", and "static" fit into that list fine, because they're ultimately
specifying a class name.
The special "void" keyword doesn't actually make sense as a contract given
PHP's calling convention - as far as the calling code's concerned, it's
equivalent to "null". So it exists only for purpose (2), constraining the
implementation for the benefit of the function's author.
$this would fit into the same category - as far as calling code is
concerned it is equivalent to "static", unless they're doing something very
specific with object identity. This makes it an odd constraint on
interfaces, for example - DateTimeInterface exists specifically to have
mutable and immutable implementations, and a return type of $this would
explicitly prevent that.
If we add ": $this" alongside ": void", I wonder where that takes us next -
what other constraints on a function can be expressed using that notation
which aren't contracts on the value seen by the caller? If we don't want to
explore that question, should we avoid adding ": $this"?
Regards,
Rowan Tommins
[IMSoP]
On Thu, Jan 9, 2020 at 4:06 PM Rowan Tommins rowan.collins@gmail.com
wrote:
However, $this is not a real type, and it is unclear what the advantage
of specifying $this rather than static would be from a type system level
perspective.Perhaps not from a "type system level", but from a more broad "enforced
contract" level.
E.g. IDEs or code inspection tools can warn if a method will not return
$this.
This also means recursive calls also need to return $this instead of
static.class C {
function foo(): static {
return clone $this;
}
function bar(): $this {
return $this->foo(); // IDE can complain.
}
}I think there are two different purposes for annotating return types:
- Contracts that tell the caller what values they should expect when
calling the function.- Constraints on the implementation which don't affect the caller, but
allow the author to catch certain bugs.The primary purpose, in my mind, is (1), with (2) generally coming as a
side-effect: if your contract is to return an int, then tools can warn you
when you don't.All concrete types can be seen this way: scalars, classes, and pseudo-types
like "iterable" are all contracts that calling code can rely on. "self",
"parent", and "static" fit into that list fine, because they're ultimately
specifying a class name.The special "void" keyword doesn't actually make sense as a contract given
PHP's calling convention - as far as the calling code's concerned, it's
equivalent to "null". So it exists only for purpose (2), constraining the
implementation for the benefit of the function's author.$this would fit into the same category - as far as calling code is
concerned it is equivalent to "static", unless they're doing something very
specific with object identity. This makes it an odd constraint on
interfaces, for example - DateTimeInterface exists specifically to have
mutable and immutable implementations, and a return type of $this would
explicitly prevent that.If we add ": $this" alongside ": void", I wonder where that takes us next -
what other constraints on a function can be expressed using that notation
which aren't contracts on the value seen by the caller? If we don't want to
explore that question, should we avoid adding ": $this"?
An argument could be made that $this does also specify a certain contract
to the caller: That the API may be used fluently or not without change in
functionality. That is
$foo->setBar();
$foo->setBaz();
must be strictly equivalent to
$foo
->setBar()
->setBaz()
;
The same is not the case for a plain "static" type. In fact, I think that
for all other uses of "static" outside of fluent interfaces, not using the
return value would be a programming error.
But still, this kind of contract is not a type-system contract, and I'm not
sure it's a good idea to mix other types of API contracts into the type
system in this fashion.
Regards,
Nikita
On Thu, Jan 9, 2020 at 4:06 PM Rowan Tommins rowan.collins@gmail.com
wrote:On Thu, 9 Jan 2020 at 14:23, Andreas Hennings andreas@dqxtech.net
wrote:However, $this is not a real type, and it is unclear what the
advantage
of specifying $this rather than static would be from a type system
level
perspective.Perhaps not from a "type system level", but from a more broad "enforced
contract" level.
E.g. IDEs or code inspection tools can warn if a method will not return
$this.
This also means recursive calls also need to return $this instead of
static.class C {
function foo(): static {
return clone $this;
}
function bar(): $this {
return $this->foo(); // IDE can complain.
}
}I think there are two different purposes for annotating return types:
- Contracts that tell the caller what values they should expect when
calling the function.- Constraints on the implementation which don't affect the caller, but
allow the author to catch certain bugs.The primary purpose, in my mind, is (1), with (2) generally coming as a
side-effect: if your contract is to return an int, then tools can warn
you
when you don't.All concrete types can be seen this way: scalars, classes, and
pseudo-types
like "iterable" are all contracts that calling code can rely on. "self",
"parent", and "static" fit into that list fine, because they're
ultimately
specifying a class name.The special "void" keyword doesn't actually make sense as a contract
given
PHP's calling convention - as far as the calling code's concerned, it's
equivalent to "null". So it exists only for purpose (2), constraining the
implementation for the benefit of the function's author.$this would fit into the same category - as far as calling code is
concerned it is equivalent to "static", unless they're doing something
very
specific with object identity. This makes it an odd constraint on
interfaces, for example - DateTimeInterface exists specifically to have
mutable and immutable implementations, and a return type of $this would
explicitly prevent that.If we add ": $this" alongside ": void", I wonder where that takes us
next -
what other constraints on a function can be expressed using that notation
which aren't contracts on the value seen by the caller? If we don't want
to
explore that question, should we avoid adding ": $this"?An argument could be made that $this does also specify a certain contract
to the caller: That the API may be used fluently or not without change in
functionality. That is$foo->setBar(); $foo->setBaz();
must be strictly equivalent to
$foo ->setBar() ->setBaz() ;
The same is not the case for a plain "static" type. In fact, I think that
for all other uses of "static" outside of fluent interfaces, not using the
return value would be a programming error.But still, this kind of contract is not a type-system contract, and I'm not
sure it's a good idea to mix other types of API contracts into the type
system in this fashion.
We currently don't have another "system" where this kind of info could be
specified.
And in this case, $this also implies static, so if we would use whichever
other system to specify $this, the type hint "static" would become
redundant.
"@return $this" is common in phpdoc (*) since a while, and so far I have
not seen any problems with it.
If we ask "where does this lead?", one natural next step might be to
specifically say that the return type is the same type, but NOT $this.
So, a promise that we really get a new object which we can modify without
changing the original object.
I don't know how we would express this. Perhaps ": clone", but this would
be too specific imo, because whether it is a clone is an implementation
detail.
In phpdoc (*) there is no common syntax for "static, but not $this", so
perhaps it was not needed yet.
And in fact, an immutable wither can safely return the original object if
no changes are needed, if other methods are also immutable.
(*) When I say "phpdoc", I really mean the kinds of docs that people
commonly use in the wild, and that are understood by IDEs.
Which of that is documented and supported by the phpdoc library is a
different question.
Regards,
Nikita
On Thu, Jan 9, 2020 at 4:06 PM Rowan Tommins rowan.collins@gmail.com
wrote:An argument could be made that $this does also specify a certain contract
to the caller: That the API may be used fluently or not without change in
functionality. That is$foo->setBar(); $foo->setBaz();
must be strictly equivalent to
$foo ->setBar() ->setBaz() ;
The same is not the case for a plain "static" type. In fact, I think that
for all other uses of "static" outside of fluent interfaces, not using the
return value would be a programming error.But still, this kind of contract is not a type-system contract, and I'm not
sure it's a good idea to mix other types of API contracts into the type
system in this fashion.We currently don't have another "system" where this kind of info could be
specified.
How about:
public fluent function doWhatever(): static
Perhaps this could be introduced at some point in the future to enforce
returning $this.
And in this case, $this also implies static, so if we would use whichever
other system to specify $this, the type hint "static" would become
redundant."@return $this" is common in phpdoc (*) since a while, and so far I have
not seen any problems with it.If we ask "where does this lead?", one natural next step might be to
specifically say that the return type is the same type, but NOT $this.
So, a promise that we really get a new object which we can modify without
changing the original object.I don't know how we would express this. Perhaps ": clone", but this would
be too specific imo, because whether it is a clone is an implementation
detail.
Maybe ": new" ?
Regards,
Dik Takken
On Thu, Jan 9, 2020 at 4:06 PM Rowan Tommins rowan.collins@gmail.com
wrote:An argument could be made that $this does also specify a certain
contract
to the caller: That the API may be used fluently or not without change
in
functionality. That is$foo->setBar(); $foo->setBaz();
must be strictly equivalent to
$foo ->setBar() ->setBaz() ;
The same is not the case for a plain "static" type. In fact, I think
that
for all other uses of "static" outside of fluent interfaces, not using
the
return value would be a programming error.But still, this kind of contract is not a type-system contract, and I'm
not
sure it's a good idea to mix other types of API contracts into the type
system in this fashion.We currently don't have another "system" where this kind of info could be
specified.How about:
public fluent function doWhatever(): static
Perhaps this could be introduced at some point in the future to enforce
returning $this.
This would work, but:
- The ": static" would be redundant if the method is fluid.
- I still would find it more natural to look into the return hint and find
": $this". With fluent + static I would have to look in two places.
But I was thinking something else related to the ": $this" (or "fluent").
If we already annotate a method as fluent, then the actual "return $this;"
statement is redundant as well.
We could make this implicit, so you no longer have to write "return
$this;".
Not sure if that's a good idea, and definitely not in scope of the ":
static" proposal. But I think it is useful to have an idea where we want to
go with this.
And in this case, $this also implies static, so if we would use whichever
other system to specify $this, the type hint "static" would become
redundant."@return $this" is common in phpdoc (*) since a while, and so far I have
not seen any problems with it.If we ask "where does this lead?", one natural next step might be to
specifically say that the return type is the same type, but NOT $this.
So, a promise that we really get a new object which we can modify without
changing the original object.I don't know how we would express this. Perhaps ": clone", but this would
be too specific imo, because whether it is a clone is an implementation
detail.Maybe ": new" ?
To me this would not imply that this has to be the same type..
Either way, I think there is no strong enough reason to introduce a syntax
for this case.
It would be mostly for wither methods, and these can safely return the
original object if the entire thing is designed as immutable.
Regards,
Dik Takken
This would work, but:
": $this". With fluent + static I would have to look in two places.
How about :fluent?
This would indicate both a type and a further constraint meaning $this.
Something to consider...?
-Mike
Hi,
After reading all the thread:
I'm +1 for : static
as proposed by this RFC.
I'm also +1 for : $this
, preferably also in PHP 8.0, but that could
be a separate RFC:
- I like the idea to check it at compile time (like
: void
), i.e.
that all the return points of the method be syntacticallyreturn $this;
(maybe also allowreturn $this->otherMethod(/*...*/);
where
the forwarded method is itself declared: $this
). - Regarding covariance,
$this
should probably be treated like a
"subtype" ofstatic
. - I don't like the idea of making an implicit
return $this;
in
addition to the check.
I'm -1 for : fluent
or fluent function
as an alternative to : $this
.
I'm -0.5 for : new
/ : clone
.
About "what comes out is the same type as what goes in", I would wait
for generics.
--
Guilliam Xavier
Hi internals,
I would like to propose the following RFC, which allows using "static" as
a return type:https://wiki.php.net/rfc/static_return_type
While I'm personally not a fan of late static binding, we do support it
and people do use it quite heavily, so I think we should also support it in
return types.Regards,
Nikita
Heads up: I plan to start voting on this RFC tomorrow.
I think most of the discussion here has been around the "$this" type
mentioned in future scope, but no particular concerns with "static" itself
have been raised. (I don't plan to include $this as part of this RFC.)
Regards,
Nikita