Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:80090 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 62918 invoked from network); 2 Jan 2015 13:01:16 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 2 Jan 2015 13:01:16 -0000 Authentication-Results: pb1.pair.com header.from=ajf@ajf.me; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=ajf@ajf.me; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain ajf.me designates 192.64.116.200 as permitted sender) X-PHP-List-Original-Sender: ajf@ajf.me X-Host-Fingerprint: 192.64.116.200 imap1-2.ox.privateemail.com Received: from [192.64.116.200] ([192.64.116.200:45933] helo=imap1-2.ox.privateemail.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 0D/20-61219-A9696A45 for ; Fri, 02 Jan 2015 08:01:15 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.privateemail.com (Postfix) with ESMTP id B9DC7B0008E; Fri, 2 Jan 2015 08:01:11 -0500 (EST) X-Virus-Scanned: Debian amavisd-new at imap1.ox.privateemail.com Received: from mail.privateemail.com ([127.0.0.1]) by localhost (imap1.ox.privateemail.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id p006dISBq40T; Fri, 2 Jan 2015 08:01:11 -0500 (EST) Received: from [192.168.0.13] (unknown [94.13.96.117]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.privateemail.com (Postfix) with ESMTPSA id E7A1AB0008A; Fri, 2 Jan 2015 08:01:09 -0500 (EST) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 8.1 \(1993\)) In-Reply-To: Date: Fri, 2 Jan 2015 13:00:37 +0000 Cc: Stanislav Malyshev , Thomas Bley , Nikita Popov , PHP Internals List Content-Transfer-Encoding: quoted-printable Message-ID: <458FFDA4-032E-46D9-BE93-E7307F98A1E6@ajf.me> References: <41D5BB0B-73AF-488E-968D-90B2878E3178@ajf.me> <20150101164402.EB1442605AB@dd15934.kasserver.com> <54A5DFCE.6030307@gmail.com> To: Marco Pivetta X-Mailer: Apple Mail (2.1993) Subject: Re: [PHP-DEV] [RFC] Scalar Type Hints From: ajf@ajf.me (Andrea Faulds) Hi Marco, > On 2 Jan 2015, at 09:16, Marco Pivetta wrote: >=20 >=20 > I'm not sure why everyone is still taking the PHP manual as a good = reference about how to write software: PHP internal functions are one of = the main reason why this language is under-appreciated. >=20 > The manual is pulling the concepts of `int`, `string` and so on out of = thin air, whereas the correct syntax in those cases is = `int|string|Stringable`, with explicit explanation of what those strings = should look like. I don=E2=80=99t see why the manual is wrong. Yes, in a strictly-typed = language which allows no conversion of arguments, foobar(int $foo) = wouldn=E2=80=99t have the behaviour PHP exhibits. Yet PHP is not a = strictly-typed language, and weakly-typed parameters are hardly a novel = concept. The language that PHP is implemented in, C, also has this. And = yet, C does not have this: void foobar(char|unsigned char|short|unsigned short|int|unsigned = int|long|unsigned long|long long|unsigned long = long|float|double|_Bool|void* foo) Why? Because in C, implicit conversions between parameter types are = permitted. PHP has the same thing for its internal/extension functions. = The manual isn=E2=80=99t wrong. > This is constraining. Constraining has nothing to do with validation = and casting: mixing the concepts of type-juggling, validation and = constraining is a huge mess (which I don't like, but it's better than = having nothing), and it would better be off using a syntax like: Argument types do not necessarily exist purely to error on invalid = input. They also exist for documentation purposes and, in languages like = C, implicit conversion. > public function __construct(ProductId $productId, (int) $amount) >=20 > This makes the difference **much more clear**, as that `(int)` is not = a constraint, it's a different, broader concept. I don=E2=80=99t think the cast-like syntax is a particularly good idea. = It=E2=80=99s inconsistent with our manual conventions (then again, many = other things are). It=E2=80=99s misleading, as well: we don=E2=80=99t do = an explicit cast. If it was an explicit cast, literally any value would = be accepted. But that=E2=80=99s not the case at all, the weakly-typed = parameters that extension functions have do not accept any value. = Instead, they accept the desired type, and a limited range of = convertible values of other scalar types. > Additionally, the BC break concern of strict type-hinting and classes = named `String`, `Int` and `Bool` (and similars) is delayed until we get = strict type-hints, as the syntax is currently not allowed by the = language and doesn't present any BC issues (http://3v4l.org/3Fqdh): I=E2=80=99d rather not delay it. We probably should have reserved syntax = for scalar hints ages ago. > @Andrea: as for the "strict" and "non-strict" PHP suggestion you had = before, please don't do that. Take following example: >=20 > function repeat(int $amount, (string) $value) { > $acc =3D ''; > $i =3D 0; >=20 > while ($i < $amount) { > $i +=3D 1; > $acc .=3D $value; > } >=20 > return $acc; > } >=20 > As you can see, mixing implicit cast and strict constraining behaviors = is perfectly fine in this case, so please don't include contextual = switches: that would be even worse IMO. I don=E2=80=99t understand why that particular example makes sense. = Since it=E2=80=99s producing a string value, surely $value should always = be a string? I really don=E2=80=99t like the idea of mixing strong- and = weakly-typed parameters. We should be consistent. Otherwise, we are = imposing too high a mental burden on programmers, who will now need to = remember which parameters are strongly-typed and which parameters are = weakly-typed. Thanks. -- Andrea Faulds http://ajf.me/