Re: [RFC] Scalar Type Hints

From: Date: Fri, 02 Jan 2015 13:00:37 +0000
Subject: Re: [RFC] Scalar Type Hints
References: 1 2 3 4 5 6  Groups: php.internals 
Request: Send a blank email to internals+get-80090@lists.php.net to get a copy of this message
Hi Marco, > On 2 Jan 2015, at 09:16, Marco Pivetta <ocramius@gmail.com> wrote: > > > 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. > > 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’t see why the manual is wrong. Yes, in a strictly-typed language which allows no conversion of arguments, foobar(int $foo) wouldn’t 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’t 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) > > This makes the difference **much more clear**, as that (int) is > not a constraint, it's a different, broader concept. I don’t think the cast-like syntax is a particularly good idea. It’s inconsistent with our manual conventions (then again, many other things are). It’s misleading, as well: we don’t do an explicit cast. If it was an explicit cast, literally any value would be accepted. But that’s 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’d 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: > > function repeat(int $amount, (string) $value) { > $acc = ''; > $i = 0; > > while ($i < $amount) { > $i += 1; > $acc .= $value; > } > > return $acc; > } > > 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’t understand why that particular example makes sense. Since it’s producing a string value, surely $value should always be a string? I really don’t 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/

« previous php.internals (#80090) next »