Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92610 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 14137 invoked from network); 21 Apr 2016 21:22:09 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 21 Apr 2016 21:22:09 -0000 Authentication-Results: pb1.pair.com header.from=php@dennis.birkholz.biz; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=php@dennis.birkholz.biz; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain dennis.birkholz.biz designates 144.76.185.232 as permitted sender) X-PHP-List-Original-Sender: php@dennis.birkholz.biz X-Host-Fingerprint: 144.76.185.232 yukon.nexxes.net Received: from [144.76.185.232] ([144.76.185.232:37329] helo=mx01.nexxes.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 0F/B6-14036-E7449175 for ; Thu, 21 Apr 2016 17:22:08 -0400 Received: from [192.168.178.29] (xdsl-81-173-161-180.netcologne.de [81.173.161.180]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) (Authenticated sender: db220660-p0g-1@packages.nexxes.net) by mx01.nexxes.net (Postfix) with ESMTPSA id 71FFD482505; Thu, 21 Apr 2016 23:22:03 +0200 (CEST) To: "guilhermeblanco@gmail.com" , Dominic Grostate References: <3cc8a4c7-2640-11ae-a67b-06f909ac1e27@texthtml.net> <57173859.4080501@rochette.cc> Cc: Mathieu Rochette , Ben Scholzen 'DASPRiD' , Josh Di Fabio , Mathieu Rochette , Sara Golemon , PHP internals , Rasmus Schultz X-Enigmail-Draft-Status: N1110 Message-ID: <5719447A.2020400@dennis.birkholz.biz> Date: Thu, 21 Apr 2016 23:22:02 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] [RFC:generics] From: php@dennis.birkholz.biz (Dennis Birkholz) Hi all, Am 20.04.2016 um 16:44 schrieb guilhermeblanco@gmail.com: > If I want to hire/move a person to a department that is registered in the > system, but is not a 3rd party company person, how would you achieve that > considering the following class structure? > > class Person {} > class Employee extends Person {} > class AssociateEmployee extends Employee {} > class Manager extends Employee {} > > Considering your function: > > function assignToDepartment(T $person) : bool; > > Generic type "T" in the function prototype needs to accept Person (new > hire), Employee and Manager (transfer), but not AssociateEmployee. > Considering upper bounds support only, your best bet is "T extends Person", > but that would accept AssociateEmployee to be provided, which contradicts > the business rule. Accepting anything lower in the hierarchy prevents new > hires. > That's when lower bounds comes into play. If you define as "T super Manager", > all Person, Employee and Manager gets accepted, but not the > AssociatedEmployee, matching properly the business rule. I have to strongly disagree with the last sentence here: "T super Manager" only fulfills your business rule by accident. If you add a "TeamLeader extends Employee" class, your complete example falls apart and shows that it is a very bad idea to introduce a "T super X" requirement. You really want "T implements Person except AssociateEmployee" so that you can use them like you would use bitmasks. I think that fundamentally contradicts how interfaces and inheritance work. The type in the generic should specify which contract (Base class/interface) you require at least inside the generic class/function. Everything else is really strange to me. What about interfaces? If Manager or Employee implement Serializable, will all other classes that implement Serializable also be allowed here? Please let's not implement "T super X" kind of generics for use cases that really need something different. Thanks, Dennis