Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:78209 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 60405 invoked from network); 21 Oct 2014 18:22:14 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 21 Oct 2014 18:22:14 -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.145.42 as permitted sender) X-PHP-List-Original-Sender: jwatzman@fb.com X-Host-Fingerprint: 67.231.145.42 mx0a-00082601.pphosted.com Linux 2.5 (sometimes 2.4) (4) Received: from [67.231.145.42] ([67.231.145.42:33605] helo=mx0a-00082601.pphosted.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 06/7A-02077-554A6445 for ; Tue, 21 Oct 2014 14:22:13 -0400 Received: from pps.filterd (m0044008 [127.0.0.1]) by mx0a-00082601.pphosted.com (8.14.5/8.14.5) with SMTP id s9LIMAdQ002089 for ; Tue, 21 Oct 2014 11:22:10 -0700 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=x9ug+UqMKNcIOENscxCdN+f1BMdQhC5Xb8f0vAd6oSc=; b=ctCsfTTueopxUv/oO0rygKSgjak4Lfp1nxR72K9g8IEigOsfj4NxhZ8e9ILbs2u5A3/6 9gWA60mZvwNJ4+KDnxAq2LVknobTKPrG/u4rg2Tvi7GUyfyNHLEp4Ur3T66H+QWiz9ii uPMoWNwk4/BzdOOFUTivaXMtZAzN5Nl+uy0= Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-00082601.pphosted.com with ESMTP id 1q5u9jg7uc-1 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 21 Oct 2014 11:22:09 -0700 Received: from m0044008 (m0044008 [127.0.0.1]) by pps.reinject (8.14.5/8.14.5) with SMTP id s9LILxiA001392 for ; Tue, 21 Oct 2014 11:22:09 -0700 Received: from mail.thefacebook.com (mailwest.thefacebook.com [173.252.71.148]) by mx0a-00082601.pphosted.com with ESMTP id 1q5u9jg7u7-1 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=OK); Tue, 21 Oct 2014 11:22:09 -0700 Received: from PRN-MBX02-2.TheFacebook.com ([169.254.5.69]) by PRN-CHUB15.TheFacebook.com ([fe80::3479:9544:c2df:1fc0%12]) with mapi id 14.03.0195.001; Tue, 21 Oct 2014 11:22:07 -0700 To: Andrea Faulds , "derick@php.net" CC: PHP Internals Thread-Topic: [PHP-DEV] [RFC] Safe Casting Functions Thread-Index: AQHP7LlZiSKK4iJP+UuYlFeFZanGU5w6MpeAgAAC1YCAAR5RgA== Date: Tue, 21 Oct 2014 18:22:07 +0000 Message-ID: <719B54C7-7048-4C5B-B251-4BCFB3C72643@fb.com> References: <66B7B28C-2651-4A71-AC2A-55D4C7BB3DDC@ajf.me> <9ADD6AAC-A402-44B6-B9AA-A3F5F8A225AD@fb.com> <6C259842-9CA7-4058-9929-59CC3C9EA503@ajf.me> In-Reply-To: <6C259842-9CA7-4058-9929-59CC3C9EA503@ajf.me> 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="Windows-1252" Content-ID: <381461BC2AA07548AB7EEB9B9052CFB0@fb.com> Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.12.52,1.0.28,0.0.0000 definitions=2014-10-21_08:2014-10-21,2014-10-21,1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 kscore.is_bulkscore=1.29086345229679e-06 kscore.compositescore=0 circleOfTrustscore=15.112 compositescore=0.999753871438137 urlsuspect_oldscore=0.999753871438137 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.999753871438137 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-1410210180 X-FB-Internal: deliver Subject: Re: [PHP-DEV] [RFC] Safe Casting Functions From: jwatzman@fb.com (Josh Watzman) On Oct 20, 2014, at 6:17 PM, Andrea Faulds wrote: >> On 21 Oct 2014, at 02:07, Josh Watzman wrote: >>=20 >> Throwing an exception or even returning NULL seems so much better than r= eturning "false" -- "false" is a boolean, not an error, and despite some hi= storical cases of PHP using "false" as a poor person's error code, it reall= y isn=92t. >=20 > Why isn=92t FALSE an error value? NULL signifies an absence of a value, n= ot a bad value. We use FALSE in a lot of places to indicate an error. Heck,= filter_var uses it for errors here. FALSE is not an error value because it is already something else. It's alre= ady a value, it's boolean false. The fact that you couldn't build a reasona= ble to_bool even if you wanted to, as I as well as others pointed out on th= is thread, indicates the very real problem with the conflation of purposes = here. Derick Rethans said it pretty well: > Then to_bool() whould return false... or true? So hence, it should be=20 > NULL, and that would also be consistent with ext/filter. You also said: >> Also, that we *couldn't* introduce a meaningful to_bool function, even i= f we decided we wanted it, indicates to me that returning false is the wron= g thing to do. >=20 > It would be possible to use a special value in that specific case. Though= , again, booleans have their own problems. I don=92t see the point in to_bo= ol(). Whether or not we actually should add to_bool is a separate issue; we, in p= rinciple, should be able to cleanly add it, since it's a very natural exten= sion to what you've already designed here. The fact that, if we used FALSE = for error that to_bool would have to be a special case, inconsistent with t= he rest, indicates to me that using FALSE is the wrong thing -- again, it's= the conflation of the boolean value FALSE, which already has this meaning,= with some error code. It shouldn't be conflated, FALSE should not be an er= ror return, it means something else. >> If you want error codes, use error codes, or use exceptions, but having = two kinds of failure, null vs false, is really confusing. >=20 > What two kinds of error? We=92re only using FALSE here. But FALSE *is* a different kind of error as you're trying to use it here, d= ifferent than NULL which is specifically designed to be an error / lack of = value. NULL doesn't mean anything else, it's a specially-designated value. = And if you don't want to use NULL for failure because you don't think this = is quite the sort of failure that NULL expresses, then throw an exception -= - FALSE is just totally the wrong thing to return. >>> =95 If strict type hinting were added, they would fail for a nullable = typehint >>=20 >> Throwing an exception also addresses this, in a much cleaner way. If you= 're worried about strict typing, then returning "false" is even worse, sinc= e the return type of, for example, to_int is now "int | bool" as opposed to= "nullable-int" or "int" (if you throw). >=20 > Exceptions make chaining more difficult. There=92s also no precedent for = using them. I think the argument about chaining was addressed by someone else. With pre= cedent, just because there's no precedent doesn't mean we can't start now := ) They really feel like the right thing to do here and elsewhere, and we ha= ve to start somewhere. >>> =95 FALSE is a traditional error value in PHP >>=20 >> Since this is a new function, one that doesn't interoperate in any compl= icated way with the existing library or affect BC, this doesn't seem that i= mportant. IMO a language should have one failure/absense-of-value, in most = cases "null", and having a weird second case seems, well, weird. >=20 > Failure and absence of value are different things and should not use the = same value. Otherwise, you are liable to confuse missing data and errors. But if you want to make that distinction, then you shouldn't use a value th= at means something else to indicate failure. You should throw an exception.= Returning FALSE is liable to replace confusion between missing data and er= rors with confusion between some other data (i.e., the boolean FALSE) and e= rrors. I might also argue that missing the data makes it clear there was an error,= and then if someone has a nullable typehint they expressly said they accep= t a lack-of-int, but an exception seems a much cleaner way to deal with thi= s anyways. >> If you have more interesting failure cases, just throw an exception, or = return null if you want, don't continue propagating a weird second kind of = null (that isn't actually null, it's a boolean false). >=20 > It=92s not a =93weird second kind of null=94, it=92s a value FALSE. Which is being used as a weird second kind of failure, as opposed to NULL w= hich is the typical failure lack-of-value, as I argue above. >> It's also interesting to look at how other languages handle failures of = this kind. Most imperative languages I know of either throw or return null;= in particular, Python, which has fairly similar type system to PHP in a lo= t of ways, throws. Functional languages do more interesting things; Haskell= does something complicated but morally equivalent to returning null. But I= 'm not aware of any language which specifically returns false. >=20 > JavaScript returns NaN here and C sets errno to an error value. PHP uses = FALSE, in some respects, like JavaScript uses NaN. But it probably shouldn't -- NaN is a special number which is not a number = (and which *would* probably pass a float type annotation, no?). FALSE isn't= a special integer which isn't an integer -- it is already something else, = it's a boolean. JS has a few special values which are specifically designat= ed as different failures or lack-of-values -- undefined, null, NaN, etc. PH= P's FALSE does *not* fall into that category -- it *does* mean something, i= t means something else, the boolean value false. (FWIW, I don't think that = the way JS does this feels quite right either, I don't like that there are = multiple sorts of non-exception failure values, but at least they return a = designated failure value that doesn't have another totally different non-er= ror meaning.) Josh Watzman