Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:81916 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 69285 invoked from network); 5 Feb 2015 12:33:12 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 5 Feb 2015 12:33:12 -0000 Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.193 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 74.125.82.193 mail-we0-f193.google.com Received: from [74.125.82.193] ([74.125.82.193:61094] helo=mail-we0-f193.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id CF/58-27691-60363D45 for ; Thu, 05 Feb 2015 07:33:11 -0500 Received: by mail-we0-f193.google.com with SMTP id k11so1160592wes.0 for ; Thu, 05 Feb 2015 04:33:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type; bh=IikbakTz07m6qKRFJsuTRopqjm3Yddnx+LFyZVMtZNI=; b=nQfR373r9TS2BabDnGuxhtPEehWAPlqT1MpfTaGD2n/sKMNlSm0bQiWrfc2ZGIn8zU M/9u6AdbeC9zQ3pklLgrcBcdJhzWuz4FjtEivsYHe5irinx1HKivSxXLxN1dkX/GuFYX qYVpYicMbgKdu3MPGglQUQfJ1CjmQeEImHiXZ9v/yAUo6DhfpemR6Kv5EMhLZy2Q8nhU 1JyrKKsjqs446kxLZEsr09lbnKXLB58QteqRsBgdYyO5UB94tnw/eR34//7LCqUK6BdV 7MEzk+YaLakH6etp1UKe/7HPJGPQV6D/lkCnP4FBlIp2PMEW/pURe4it0VPCvwpEp4Ni Q5AA== X-Received: by 10.194.109.36 with SMTP id hp4mr7090086wjb.17.1423139588193; Thu, 05 Feb 2015 04:33:08 -0800 (PST) Received: from [192.168.0.172] ([62.189.198.114]) by mx.google.com with ESMTPSA id 18sm7168880wjr.46.2015.02.05.04.33.07 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Feb 2015 04:33:07 -0800 (PST) Message-ID: <54D362FB.1010401@gmail.com> Date: Thu, 05 Feb 2015 12:32:59 +0000 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-Version: 1.0 To: internals@lists.php.net References: <4A36329B-F17B-4665-A84E-D8CF01F5B29A@ajf.me> <007e01d0413d$92e70ad0$b8b52070$@tutteli.ch> In-Reply-To: <007e01d0413d$92e70ad0$b8b52070$@tutteli.ch> Content-Type: multipart/alternative; boundary="------------010305020709090005090609" Subject: Re: AW: [PHP-DEV] Allow dropping typehints during inheritance From: rowan.collins@gmail.com (Rowan Collins) --------------010305020709090005090609 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Robert Stoll wrote on 05/02/2015 12:16: >> -----Ursprüngliche Nachricht----- >> Von: julienpauli@gmail.com [mailto:julienpauli@gmail.com] Im Auftrag von Julien Pauli >> Gesendet: Donnerstag, 5. Februar 2015 13:10 >> An: Andrea Faulds >> Cc: Hannes Magnusson; Nikita Popov; PHP internals >> Betreff: Re: [PHP-DEV] Allow dropping typehints during inheritance >> >> On Thu, Feb 5, 2015 at 2:08 AM, Andrea Faulds wrote: >> >>> Hi Hannes, >>> >>>> On 4 Feb 2015, at 23:58, Hannes Magnusson >>>> >>> wrote: >>>> So what it supports "more inputs"? >>>> It does constitute an LSP violation. "more inputs" is not what the >>>> guarantee is at all, if that is what you want you'd typehint on a >>>> interface. >>>> >>>> >>>> It is a LSP failure to allow a string, or any other scalar value, >>>> when the parent requires a specific type/object. >>>> >>>> It sucks that we fail our arginfo very frequently, but this is the >>>> way >>> it is :] >>> >>> An interface requires only a minimum standard for accepted input. If a >>> class implementing that interface allows a wider range of values, but >>> still allows at least what the interface requires it to, it is not an >>> LSP violation. Scalars are not special. >>> >> If we allow larger type, why doesn't such code work ? >> >> interface A { } >> interface B extends A { } >> >> class C { >> public function foo(A $a) { } >> } >> >> class D extends C { >> public function foo(B $a) { } // E_STRICT } >> >> This is wrong IMO. >> > Because this would be covariance and violates LSP. Considering the following: > > function foo(C $c){ > $c->foo(new A); > } > > if you substitute C with D then suddenly the code would not work anymore. Indeed. The contract states that if you know you have an instance of C, you can pass any instance of A to its foo method. If you are given an instance of D, that contract will be violated, because instances of A which are not instances of B will be rejected. The other way around, however, is theoretically fine (though not implemented in PHP because its complicated to check): class X { public function bar(B $thing) {} } class Y extends X { public function bar(A $thing) {} } Here, the contract states that if you have an instance of X, you can pass any instance of B to its bar method. If you are given an instance of Y, you can still pass any B to its bar method, so the contract is met. If you /know/ that you have an instance of Y, you know you can also pass other types of A//. A real-life example that came to mind previously was an event handler interface that told implementers exactly what kind of event to expect, being implemented by a logger that can actually accept any kind of event you give it. As long as the event dispatchers knows that the logger accepts the event its dispatching, it doesn't care what else it can do. Regards, -- Rowan Collins [IMSoP] --------------010305020709090005090609--