Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92367 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 47316 invoked from network); 16 Apr 2016 11:09:35 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 16 Apr 2016 11:09:35 -0000 Authentication-Results: pb1.pair.com smtp.mail=php@fleshgrinder.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=php@fleshgrinder.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain fleshgrinder.com from 212.232.25.164 cause and error) X-PHP-List-Original-Sender: php@fleshgrinder.com X-Host-Fingerprint: 212.232.25.164 mx208.easyname.com Received: from [212.232.25.164] ([212.232.25.164:34997] helo=mx208.easyname.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id B4/F1-32052-C6D12175 for ; Sat, 16 Apr 2016 07:09:33 -0400 Received: from cable-81-173-133-226.netcologne.de ([81.173.133.226] helo=[192.168.178.20]) by mx.easyname.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1arO6R-0005mV-JF; Sat, 16 Apr 2016 11:09:27 +0000 Reply-To: internals@lists.php.net References: <570E99AC.3090804@fleshgrinder.com> <570EA5EB.8090501@fleshgrinder.com> <570EAB0D.6080706@gmail.com> <570EB67E.8010908@garfieldtech.com> <5B147E88-CC0A-4CBC-A49D-C7FE3BF557C0@zend.com> <6F.C3.12455.94C5F075@pb1.pair.com> <20160414094440.GF19347@phcomp.co.uk> <570FD94F.90703@fleshgrinder.com> <570FE8A9.4020809@gmail.com> <570FEE98.1030401@fleshgrinder.com> <570FEF32.2000107@fleshgrinder.com> <570FF69F.6010004@gmail.com> To: Stanislav Malyshev , internals@lists.php.net, Larry Garfield Message-ID: <57121D46.5060208@fleshgrinder.com> Date: Sat, 16 Apr 2016 13:08:54 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.7.2 MIME-Version: 1.0 In-Reply-To: <570FF69F.6010004@gmail.com> Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="SRmsJ3poK35DB1ndreJt8dF6eq0KqXw6D" X-ACL-Warn: X-DNSBL-BARRACUDACENTRAL Subject: Re: [PHP-DEV] Re: Improving PHP's type system From: php@fleshgrinder.com (Fleshgrinder) --SRmsJ3poK35DB1ndreJt8dF6eq0KqXw6D Content-Type: multipart/mixed; boundary="tcEln9NUIt1JTnaB4sWP21lpkg1fvC1SN" From: Fleshgrinder Reply-To: internals@lists.php.net To: Stanislav Malyshev , internals@lists.php.net, Larry Garfield Message-ID: <57121D46.5060208@fleshgrinder.com> Subject: Re: [PHP-DEV] Re: Improving PHP's type system References: <570E99AC.3090804@fleshgrinder.com> <570EA5EB.8090501@fleshgrinder.com> <570EAB0D.6080706@gmail.com> <570EB67E.8010908@garfieldtech.com> <5B147E88-CC0A-4CBC-A49D-C7FE3BF557C0@zend.com> <6F.C3.12455.94C5F075@pb1.pair.com> <20160414094440.GF19347@phcomp.co.uk> <570FD94F.90703@fleshgrinder.com> <570FE8A9.4020809@gmail.com> <570FEE98.1030401@fleshgrinder.com> <570FEF32.2000107@fleshgrinder.com> <570FF69F.6010004@gmail.com> In-Reply-To: <570FF69F.6010004@gmail.com> --tcEln9NUIt1JTnaB4sWP21lpkg1fvC1SN Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 4/14/2016 9:59 PM, Stanislav Malyshev wrote: > Hi! >=20 >>> Reduce assertions*, enhance self-documentation, making code more robu= st, >>> perform checks in the VM and not in userland, ... >=20 > You don't reduce assertions, you just make them more cryptic and change= > error message slightly. >=20 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. >=20 > Not sure what are you referring here to, but I suspect you are trying t= o > reimplement weak typing in some partial inconsistent and strange way, > while pretending it's strong typing. >=20 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(); } } =2E.. is still much better than ... function fn($arg) { if ($arg instanceof Foo) { $arg->foo(); } elseif ($arg instanceof Bar) { $arg->bar(); } else { // ???? } } =2E.. 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 =3D (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.ph= p#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. :) --=20 Richard "Fleshgrinder" Fussenegger --tcEln9NUIt1JTnaB4sWP21lpkg1fvC1SN-- --SRmsJ3poK35DB1ndreJt8dF6eq0KqXw6D Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJXEh1aAAoJEOKkKcqFPVVrPjsP/2onypQT07tTP/c1LOxX5bB3 5dJb2vdDmgLNWq0IqgzzIJSapnyjz/zRLjZN0og7041WFq5NB/TvHJWmJG7vGTLO CSSYPYQ7HMylWmN0DoaBWRQRoQri8dlfytjq8SstOOvc3PhD/K+nYDfJkBx/DXXp ayp1pcavQrR3HbqQgCUCqoijez12tQbYv/vOiT2KXMxXSpd3a+Qz6vD7ueoAYZY8 CZI7gHYyhcTar1WNxFqV9Ot0CQ5aG5ogym7WRm4c0jPvj/Fo1dlpLxMYZsFKqMlS VcnC5pP1zP4GtYJETpf2hz9lfcCTK69ffGYTP/m0SDh0EX69QfyhYKqXJtqS+YAj pBTLQJC/dnzmFWHhB+3oxGGNa+QTCUsWwQOMprZTUGpjsTyAf8h03RyobBxsbZka gguMtcCLAn+O8IoGuTwSIKW9bAJ4ojRw+G6o9qaNWwG53LbCtZSG6Nvgd6Ubn6nk 4s1B4XzuAwfAIjSeuzUVCVOTrDZuuTZgK5TKL4pe2BTngqUrjYlXuc8M7xDNmAcQ YtQF5yNDFRfmEYZMDvAr4NHui6DDNnNBCJgOoYtXE44HaTQW8iFRrXdxsIsgLmeX enaEk/FCqGIVwXGxQnxS5lruNFlNg+lHPSf7K5o2GRU4aUM2H7WUPjM8agtCGq6y Z9cL3lZkxENDTLeTeSK6 =yPqu -----END PGP SIGNATURE----- --SRmsJ3poK35DB1ndreJt8dF6eq0KqXw6D--