Hi Andreas,
On 18/06/2020 17:02, Andreas Hennings wrote:
I am ok with restricting the use of "return *;" inside a constructor.
But I don't like allowing the ": void" declaration.
The way I look at it, constructors are mostly declared like a normal
method - they use the keyword "function"; can be marked public, private,
protected, abstract, and final; and can have a parameter list, with
types and defaults - so the surprising thing is that there is a special
rule *forbidding* them from having a return specifier.
If we were designing the language from scratch, would there be any
particular reason to *add* that restriction?
On 18/06/2020 21:49, Andreas Hennings wrote:
On the other hand, for a constructor the ": void" is just stating the
obvious.
Even if you see a constructor without ": void", you still know that this is
not meant to return anything.
Either because it is generally agreed to be bad (PHP7) or because it is
deprecated (PHP8) or because it is illegal (PHP9)
As long as it's possible to return things from constructors, then it is
"obvious" that a given constructor is void only in the same way that it
is "obvious" that a method called "convertToArray" returns an array. I
would be surprised if any style guide would forbid writing "public
function convertToArray(): array", so would be equally surprised to see
one forbid writing "public function __construct(): void". In both cases,
the extra marker takes the reader from 99% certain to 100%.
If in future the rules are tightened so that constructors implicitly
apply the same restriction as if they were labelled ": void", then it is
instead "meaningless" in the same sense that the ": Traversable" is
meaningless in this code:
class Foo implements IteratorAggregate {
// ...
public function getIterator(): Traversable {
// ...
}
}
For historical reasons, the IteratorAggregate interface doesn't require
the method to declare its return type, but the code using it performs
the same check as if it did. Enforcing "voidness" on constructors feels
similar - if there was no concern for backwards compatibility, we would
probably enforce that getIterator() was marked with ": Traversable" (or
an appropriate sub-type), and __construct() was marked ": void", and
leave the rest of the logic to the generic code for handling those
declarations.
Again, I would be surprised if any style guide would forbid writing
"getIterator(): Traversable" just because the check is already enforced
implicitly by a different mechanism.
Regards,
--
Rowan Tommins (né Collins)
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php