On Thu, 9 Jan 2020 at 14:23, Andreas Hennings <andr...@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:

1) Contracts that tell the caller what values they should expect when
calling the function.
2) 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]

Reply via email to