Re: [RFC][Discussion] Return Type Variance Checking

From: Date: Tue, 25 Nov 2014 22:19:32 +0000
Subject: Re: [RFC][Discussion] Return Type Variance Checking
References: 1 2 3 4  Groups: php.internals 
Request: Send a blank email to internals+get-79183@lists.php.net to get a copy of this message
Am 25.11.2014 um 23:13 schrieb Marc Bennewitz:
Am 25.11.2014 um 22:43 schrieb Levi Morrison:
On Tue, Nov 25, 2014 at 2:07 PM, Marc Bennewitz <dev@mabe.berlin> wrote:
I think it's required to do the type check on runtime (Option 2) because one of the use cases for return type-hint are factories and such often do instantiation in base of unknown string values: class MyFactory {
     public static function factory($name) : AdapterInterface {
         $class = 'MyNamespace\Adapter\' . $name;
         return $class();
     }
}
It seems that I did not explain this clearly enough; I apologize. The variance has to do with the declared type in the function signature when inheritance is involved, not the type of the value returned by the function. For instance, under any of the three options this code will work just fine: class Foo {} class Goo extends Foo {} class FooFactory {
     function create(): Foo { return new Goo(); }
} As long as the return value from FooFactory::create returns Foo or a subtype of Foo (such as Goo), then it will work. The variance that is under discussion in this thread is about the declared return type in the signature: class GooFactory extends FooFactory {
     function create(): Goo {}
} In this case, GooFactory::create() declares a return type of Goo, which is a subtype of Foo [the return type of the inherited method FooFactory::create()]. This is a covariant return type. If we choose option 3, the only possible return type for GooFactory::create is Foo. Hopefully this clarifies the issue.
Yes it does - thank you for explanation - my mistake :/ Option 3 is a no go not from OOP perspective and from consistency pov as we already allow this in type-hint: class FooFactory {
    function create(Foo $foo): Foo { return $foo; }
} class GooFactory extends FooFactory {
    function create(Goo $goo): Goo { return $goo; }
} OK HHVM allows it - we also allow it but trigger an E_STRICT error
@see http://3v4l.org/UhtOb

« previous php.internals (#79183) next »