Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:93733 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 28402 invoked from network); 2 Jun 2016 20:56:39 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 2 Jun 2016 20:56:39 -0000 Authentication-Results: pb1.pair.com header.from=bobwei9@hotmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=bobwei9@hotmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain hotmail.com designates 65.55.111.110 as permitted sender) X-PHP-List-Original-Sender: bobwei9@hotmail.com X-Host-Fingerprint: 65.55.111.110 blu004-omc2s35.hotmail.com Received: from [65.55.111.110] ([65.55.111.110:57993] helo=BLU004-OMC2S35.hotmail.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C4/80-24756-38D90575 for ; Thu, 02 Jun 2016 16:56:39 -0400 Received: from BLU436-SMTP208 ([65.55.111.73]) by BLU004-OMC2S35.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.23008); Thu, 2 Jun 2016 13:56:33 -0700 X-TMN: [e6yGYCAfmVfyscSetP0v3m28Q0YnizfM] X-Originating-Email: [bobwei9@hotmail.com] Message-ID: Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 (Mac OS X Mail 9.2 \(3112\)) In-Reply-To: <68b821ac-d71f-4be5-8dca-ae94db332630@gmail.com> Date: Thu, 2 Jun 2016 22:56:28 +0200 CC: internals@lists.php.net Content-Transfer-Encoding: quoted-printable References: <0A.C5.62101.1C860575@pb1.pair.com> <68b821ac-d71f-4be5-8dca-ae94db332630@gmail.com> To: Rowan Collins X-Mailer: Apple Mail (2.3112) X-OriginalArrivalTime: 02 Jun 2016 20:56:31.0256 (UTC) FILETIME=[3D64B980:01D1BD11] Subject: Re: [PHP-DEV] Re: [RFC] [PRE-VOTE] Union types From: bobwei9@hotmail.com (Bob Weinand) > Am 02.06.2016 um 22:25 schrieb Rowan Collins = : >=20 > On 02/06/2016 18:43, Bob Weinand wrote: >> We had that exact idea relatively early, but it exposes other = problems=E2=80=A6 order suddenly matters. You cannot just add "a" type = and get the expected results. >>=20 >> E.g. >> function f(true | string $foo) { ... } >>=20 >> everything except 0, =C2=B10, "0" and "" would now return true. = That's totally WTF. Sure, it's more friendly for people who want to = read*rules*. But it is very bad for intuitivity. >=20 > I'm not so sure about that - the RFC already mentions the mnemonic = that "|" means "or", and anyone reading PHP code should be familiar with = short-cutting boolean operators, so this feels kind of natural to me: = "$foo must be true OR a string". Thus "I would prefer it to be true, but = if not, will accept a string". This is a bitwise or (as in constant flags), where all modes are = allowed. It's not a boolean or, whose mnemonic is "||" (not "|"). >> Also: >>=20 >>> >function i(string | int) { echo gettype($number); } >>> >i('10'); // string >>> >i(10); // string >> This. This is especially bad as it has different behaviors in strict = and weak mode then. That's a no-go. >=20 > Again, the logic is "I would prefer a string if you can, but an int if = not"; if weak mode tries its best to match that specification, it will = always land on a string coercion. And again, in strict mode, this would result in an integer - but not in = weak mode. (because strict types mandates no cast). This is a no-go, no = matter what. > It's more of a problem the other way around, though, because I'd = forgotten that weak mode is allowed to perform lossy casts: >=20 > function f ( int | string $number ) { echo $number; } > f('1a'); >=20 > In weak mode, this would echo "1", because the int cast succeeds, = lossily. That's a little odd, I admit. >=20 >=20 > The rules are much clearer in table form, by the way, thumbs up for = that. :) Although it would be nice to point to some documentation of = where these rules were lifted from, given the claim that "they are not = the invention of this proposal". E.g. object->string is possible right now and is preserved (but = object->int etc. aren't). Or a non-numeric string cannot be passed to neither int nor float; thus = not possible to pass them to int|float.=20 > Looking at them, I see there is one extra rule which doesn't seem to = be consistent with normal weak typing, but is trying very hard to be = lossless, and that's "float -> int (if lossless)" as a separate priority = from "float -> int". I'm not strictly opposed here. If more people agree here I may change = that. > Current loose typing performs no such check: >=20 > function f(int $x) { echo gettype($x), ':', $x; } > f(4.5); // integer:4 >=20 > But the proposal is that this will prefer a string a cast: >=20 > function f(int | string $x) { echo gettype($x), ':', $x; } > f(4.5); // string:4.5 >=20 > If you get rid of this extra rule, the order of checks actually = becomes a simple priority order, regardless of source type: [exact = match], int, float, string, boolean. >=20 >=20 > If the aim is to be lossless, then perhaps the order could be tweaked = to make lossy casts always lower priority: string, float, int, boolean? = That's technically lossy when passing int(9007199254740993) to "float | = int" because it's above the safe threshold of 2^53, but the current = implementation is already lossy when passing it to "float | string": >=20 > function f(float | string $x) { var_export($x); } > f(9007199254740993); // 9007199254740992.0 Yes, but this same behavior we have with strict types and we shall = adhere to that. Bob >=20 > Regards, >=20 > --=20 > Rowan Collins > [IMSoP]