On 2 January 2015 at 01:01, Stanislav Malyshev <smalys...@gmail.com> wrote:
> Hi! > > > The problem is that the current proposed hints/casts are deviating from > the > > type-hints that we are used to, therefore this particular feature should > > Let's check the manual we're used to. > http://php.net/manual/en/function.substr.php > > string substr ( string $string , int $start [, int $length ] ) > > What "string" and "int" mean there? How they work? What we're > "deviating" from? 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. This is what you currently do in a real-world scenario (due to the lack of hints for internal types): class Shipment { public function __construct(ProductId $productId, $amount) { if (! is_int($amount)) { throw new InvalidArgumentException(sprintf('Provided $amount must be integer, %s given', gettype($amount))); } $this->productId = $productId; $this->amount = $amount; } } No allowance of weird values passed in: why would my software ever pass an invalid $amount to my constructor? That's where I'd put a hard-failing assertion instead. This is what I'd like it to be: class Shipment { public function __construct(ProductId $productId, int $amount) { $this->productId = $productId; $this->amount = $amount; } } Following code MUST cause a hard failure: new Shipment($bananasId, '1 of a whole lot'); 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: class Shipment { public function __construct(ProductId $productId, (int) $amount) { $this->productId = $productId; $this->amount = $amount; } } This makes the difference **much more clear**, as that `(int)` is not a constraint, it's a different, broader concept. I'd rather have the new behavior suggested by Andrea with a syntax that makes this subtle yet gigantic difference explicit. 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): function sum((float) $a, (float) $b) { } >From an implementation perspective, it should just be a parser change. @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. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/