Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:93740 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 69683 invoked from network); 3 Jun 2016 10:17:04 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 3 Jun 2016 10:17:04 -0000 Authentication-Results: pb1.pair.com header.from=mails@thomasbley.de; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=mails@thomasbley.de; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain thomasbley.de from 85.13.128.151 cause and error) X-PHP-List-Original-Sender: mails@thomasbley.de X-Host-Fingerprint: 85.13.128.151 dd1730.kasserver.com Received: from [85.13.128.151] ([85.13.128.151:46785] helo=dd1730.kasserver.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id ED/31-56709-E1951575 for ; Fri, 03 Jun 2016 06:17:03 -0400 Received: from dd1730.kasserver.com (dd0800.kasserver.com [85.13.143.204]) by dd1730.kasserver.com (Postfix) with ESMTPSA id D466A1A81FC5; Fri, 3 Jun 2016 12:16:59 +0200 (CEST) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-SenderIP: 88.67.42.43 User-Agent: ALL-INKL Webmail 2.11 In-Reply-To: References: <0A.C5.62101.1C860575@pb1.pair.com> <68b821ac-d71f-4be5-8dca-ae94db332630@gmail.com> To: rowan.collins@gmail.com, bobwei9@hotmail.com Cc: internals@lists.php.net Message-ID: <20160603101659.D466A1A81FC5@dd1730.kasserver.com> Date: Fri, 3 Jun 2016 12:16:59 +0200 (CEST) Subject: Re: [PHP-DEV] Re: [RFC] [PRE-VOTE] Union types From: mails@thomasbley.de ("Thomas Bley") why not try all types weakly from left to right in weak mode? Rule: if type check would give a fatal error for a type, try next type. E.g. function i(int | string $var) { echo gettype($var) . ' ' . $var; } i('10'); // int 10 i('10a'); // int 10 i('foo'); // string foo i(10.0); // int 10 i(10); // int 10 Regards Thomas Bob Weinand wrote on 02.06.2016 22:56: > >> Am 02.06.2016 um 22:25 schrieb Rowan Collins : >> >> On 02/06/2016 18:43, Bob Weinand wrote: >>> We had that exact idea relatively early, but it exposes other problems… >>> order suddenly matters. You cannot just add "a" type and get the expected >>> results. >>> >>> E.g. >>> function f(true | string $foo) { ... } >>> >>> everything except 0, ±0, "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. >> >> 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: >>> >>>> >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. >> >> 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: >> >> function f ( int | string $number ) { echo $number; } >> f('1a'); >> >> In weak mode, this would echo "1", because the int cast succeeds, lossily. >> That's a little odd, I admit. >> >> >> 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. > >> 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: >> >> function f(int $x) { echo gettype($x), ':', $x; } >> f(4.5); // integer:4 >> >> But the proposal is that this will prefer a string a cast: >> >> function f(int | string $x) { echo gettype($x), ':', $x; } >> f(4.5); // string:4.5 >> >> 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. >> >> >> 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": >> >> 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 > >> >> Regards, >> >> -- >> Rowan Collins >> [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >