On 4/14/2016 9:59 PM, Stanislav Malyshev wrote: > Hi! > >>> Reduce assertions*, enhance self-documentation, making code more robust, >>> perform checks in the VM and not in userland, ... > > You don't reduce assertions, you just make them more cryptic and change > error message slightly. >
e.g. https://secure.php.net/mysqli.affected-rows#refsect1-mysqli.affected-rows-returnvalues >> Oh oh oh, I forgot the very important unions *int|string* and >> *float|string* for overflows as one can encounter them from time to >> time; even in native code. > > Not sure what are you referring here to, but I suspect you are trying to > reimplement weak typing in some partial inconsistent and strange way, > while pretending it's strong typing. > Nope, I want to strengthen from weak to almost-strict for real use-cases as outlined before. Of course there are other and better possibilities but Larry Garfield already outlined it much better than I ever could why they might not be as useful as union and intersection types. Also, I never said that one does not require additional checks, however ... function fn(Foo|Bar $arg) { if ($arg instanceof Foo) { $arg->foo(); } else { $arg->bar(); } } ... is still much better than ... function fn($arg) { if ($arg instanceof Foo) { $arg->foo(); } elseif ($arg instanceof Bar) { $arg->bar(); } else { // ???? } } ... and currently one can handle it only as ... /** * @param Foo|Bar $arg */ function fn($arg) { assert('$arg instanceof Foo || $arg instanceof Bar'); if ($arg instanceof Foo) { $arg->foo(); } else { $arg->bar(); } } This is an explanatory example real world usage for me is mainly handling and decorating of built-in PHP stuff. function fn(string|Stringable $s) { // Avoid having type casts everywhere and handle it where // needed. $s = (string) $s; } function fn(int|string $i) { // Handle scalar and big integer } function fn(float|string $f) { // Handle scalar and real number } function fn(array|Traversable $t) { // foreach } public function getLastInsertId(): int|string { return $this->mysqli->insert_id; } // No easy check for big int possible anymore. :( public function getLastInsertId(): string { return (string) $this->mysqli->insert_id; } // Note that this currently would be my preferred way of handling // this case because one should not perform arithmetic operations // on an ID. However, I sadly see it happening all the time... // Would be awesome but operator overloading is not supported. :( public function getLastInsertId(): NaturalNumber { return new NaturalNumber($this->mysqli->insert_id); } // This works with integers but there is no equivalent for real // numbers available. :( // // Extending of GMP in userland is not possible and hence adding // restrictions to it (e.g. above NaturalNumber or a // PositiveNaturalNumber) is not possible and again needs to be // spread among the whole code base. public function getLastInsertId(): GMP { return gmp_init($this->mysqli->insert_id, 10); } ---- public function findEntityById(int $id): ?Entity { // Not acceptable because we have a BIGINT. } ---- https://github.com/Fleshgrinder/php-assertion/blob/master/src/Variable.php#L492-L512 public function findEntityById(string $id): ?Entity { assert('\Variable::isPositiveNaturalNumber($id)'); } /** @throws EntityNotFound */ public function getEntityById(string $id): Entity { assert('\Variable::isPositiveNaturalNumber($id)'); } ---- public function findEntityById(GMP $id): ?Entity { assert('$id > 0'); } /** @throws EntityNotFound */ public function getEntityById(GMP $id): Entity { assert('$id > 0'); } ---- public function findEntityById(PositiveNaturalNumber $id): ?Entity { // DRY + secure :) } /** @throws EntityNotFound */ public function getEntityById(PositiveNaturalNumber $id): Entity { // DRY + secure :) } Ergo, I am not saying that union and intersection types are the solution for all problems in this world. I am only saying that they have their seldom special use cases. Please note, I am all in if we decide here to not allow union and intersection and instead fix the type mixture in PHP and add other features that allow us to create stricter types in userland code. :) -- Richard "Fleshgrinder" Fussenegger
signature.asc
Description: OpenPGP digital signature