Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:79389 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 96303 invoked from network); 2 Dec 2014 21:35:42 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 2 Dec 2014 21:35:42 -0000 Authentication-Results: pb1.pair.com smtp.mail=jwatzman@fb.com; spf=unknown; sender-id=unknown Authentication-Results: pb1.pair.com header.from=jwatzman@fb.com; sender-id=unknown Received-SPF: unknown (pb1.pair.com: domain fb.com does not designate 67.231.153.30 as permitted sender) X-PHP-List-Original-Sender: jwatzman@fb.com X-Host-Fingerprint: 67.231.153.30 mx0b-00082601.pphosted.com Linux 2.5 (sometimes 2.4) (4) Received: from [67.231.153.30] ([67.231.153.30:37771] helo=mx0a-00082601.pphosted.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id FE/C2-13722-DA03E745 for ; Tue, 02 Dec 2014 16:35:41 -0500 Received: from pps.filterd (m0004003 [127.0.0.1]) by mx0b-00082601.pphosted.com (8.14.5/8.14.5) with SMTP id sB2LXghl031537 for ; Tue, 2 Dec 2014 13:35:38 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-id : content-transfer-encoding : mime-version; s=facebook; bh=xSly7kvPPoRcLgkW2zJLzLMfBOU2xMT6UUIT9d/3tzw=; b=U22HhmSkPX15zrQ33JVUHWNt0o8eMto9J6ynsKdOftTnEEIpYtQ3CT9Nuo0kzYqo5yT9 ZZsO5pueLKMMTWC61r+gvul8MpWvqxzqV05ZmJ9GQDnMa6rEB+ehiBAzdnyxj4SQFrUT YxW9qu3ez514zk1p+p6rWbDh8gO5GyXkiBM= Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-00082601.pphosted.com with ESMTP id 1r1n4y83g2-1 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 02 Dec 2014 13:35:38 -0800 Received: from m0004003 (m0004003 [127.0.0.1]) by pps.reinject (8.14.5/8.14.5) with SMTP id sB2LYOfJ032343 for ; Tue, 2 Dec 2014 13:35:37 -0800 Received: from mail.thefacebook.com ([199.201.64.23]) by mx0b-00082601.pphosted.com with ESMTP id 1r1n4y83fu-4 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=OK); Tue, 02 Dec 2014 13:35:37 -0800 Received: from PRN-MBX02-2.TheFacebook.com ([169.254.5.125]) by PRN-CHUB09.TheFacebook.com ([fe80::b128:36fa:e69b:a338%12]) with mapi id 14.03.0195.001; Tue, 2 Dec 2014 13:35:35 -0800 To: Stanislav Malyshev CC: "guilhermeblanco@gmail.com" , Rowan Collins , PHP internals Thread-Topic: [PHP-DEV] [RFC] Abstract final classes Thread-Index: AQHQCfUHwSNZMDBLqUOftPvN8Cufipx0+kkAgAAPLgCAARN2gIAHRRWA Date: Tue, 2 Dec 2014 21:35:34 +0000 Message-ID: <9C4E199C-2129-45B4-91E8-5D7652E1AE9A@fb.com> References: <547723A8.8090008@gmail.com> <54781777.6090208@gmail.com> In-Reply-To: <54781777.6090208@gmail.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [192.168.16.4] Content-Type: text/plain; charset="us-ascii" Content-ID: <98BE691B87704D45B90DC8E526B1FE85@fb.com> Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.13.68,1.0.33,0.0.0000 definitions=2014-12-02_08:2014-12-02,2014-12-02,1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 kscore.is_bulkscore=2.94209101525666e-14 kscore.compositescore=0 circleOfTrustscore=15.112 compositescore=0.994924612563162 urlsuspect_oldscore=0.994924612563162 suspectscore=0 recipient_domain_to_sender_totalscore=0 phishscore=0 bulkscore=0 kscore.is_spamscore=0 recipient_to_sender_totalscore=0 recipient_domain_to_sender_domain_totalscore=1889 rbsscore=0.994924612563162 spamscore=0 recipient_to_sender_domain_totalscore=0 urlsuspectscore=0.9 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=7.0.1-1402240000 definitions=main-1412020177 X-FB-Internal: deliver Subject: Re: [PHP-DEV] [RFC] Abstract final classes From: jwatzman@fb.com (Josh Watzman) On Nov 27, 2014, at 10:34 PM, Stanislav Malyshev wrot= e: >> You are correct. Methods cannot be declared abstract if you have an >> "abstract final". They must also be static. I added these checks togethe= r >=20 > To me, it just feels a bit unnatural. So you have abstract class, which > usually has abstract methods. Then you have "abstract final" class which > can not have abstract methods, but instead should have "static" methods. > This just sounds a bit weird to me - adding "final" to description of > the class completely changes all the rules in very unexpected direction. What does it mean to have an abstract static function? Abstract (non-static= ) functions make sense for abstract classes -- since you cannot instantiate= the abstract class, you know that the instantiable subclass that you actua= lly have an instance of must have implemented the method, so it's safe to c= all. But you *can* call static methods on abstract classes, and so you have= no guarantee that the abstract static method exists -- and you need to be = very careful with LSB to actually call it correctly anyways. Does this mean that static classes with abstract methods (or abstract stati= c classes, or however this ends up working out syntactically) won't be allo= wed to have static methods called on them directly? How do you make sure th= at the methods in them do the right LSB stuff to call the abstract static f= unctions correctly? Inheritance semantics for static classes also get messy when you start deal= ing with traits. As a quick example, the current proposal only allows stati= c classes to inherit from other static classes... but where do traits fit i= n here? Only traits with only static methods are allowed to be included? Th= is could lead to some very annoying refactoring scenarios where changing a = trait that is used in several places leads to errors with static classes...= traits bring up many of the same issues as multiple inheritance, and I thi= nk you'll have some of those issues here. All of the above is the crux of the issue of why Hack went with "abstract f= inal" and not anything else. Abstract does not mean "must be subclassed" --= you can have an abstract class with no subclasses and still call static me= thods on it; this is perfectly meaningful, and is at least how I emulated "= abstract final" before Hack got the feature. Abstract means "cannot be inst= antiated" (and, since it cannot be instantiated, may contain *instance* met= hods with empty bodies, i.e., abstract methods). Then final means "cannot b= e subclassed" -- so the two together means you have a class that has no ins= tances itself, and cannot be subclasses, so you can never have an object of= that type. The use cases for being able to override such a class are quest= ionable at best, as above. This really is just the combination of two existing class modifiers -- no n= eed to introduce a new "static" modifier. And it leads to lots of interesti= ng issues, as above. Josh Watzman