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

Reply via email to