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]