Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:111897 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 79228 invoked from network); 18 Sep 2020 05:20:01 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 18 Sep 2020 05:20:01 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 658A71804E3 for ; Thu, 17 Sep 2020 21:28:46 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.6 required=5.0 tests=BAYES_00,BODY_8BITS, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from srv015.mail.ichtushosting.com (srv015.mail.ichtushosting.com [159.69.182.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 17 Sep 2020 21:28:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=stitcher.io ; s=default; h=To:References:Message-Id:Content-Transfer-Encoding:Cc:Date: In-Reply-To:From:Subject:Mime-Version:Content-Type:Sender:Reply-To:Content-ID :Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To: Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe :List-Post:List-Owner:List-Archive; bh=PCxFwSKU+8Ol6XEi+LVmXxekC/nShHyHDDEfY7JRF/s=; b=GOGEkC4/9pqdP1DXPoWUrecbN7 Hj670piodAxITGzEn1wBBjb+KfX79F8D8c/Fow5Fua/FZ8Y3MnaXw3di37qjbyfL/I18CNdP5z6l2 Lk0d7zQd9o1SR5WBpsijz7jlXfZqTtkpb140KT88IhRI/DiyTEzpG4JpoTdQXpeylkRkyVCKrVy1S Vq5UHWKJCb2KlOzHutDg2IUOs5MdwGsUXFIcq/WNgf7W3/j6ua6R3nfrHqfg7Zh2+ocjuqYYV0ul4 pJDsvn9F9VQqV8VUYRREcmB1WK8g3tuVkrusVhZ3EcECI2+VJO1AiM8xX1QVzATTV12PQHaVQq7ci Rp7Wr9/Q==; Received: from srv021.web.ichtushosting.com ([78.47.76.72]) by srv015.mail.ichtushosting.com stage1 with esmtp (Exim MailCleaner) id 1kJ80o-00044r-Sc from ; Fri, 18 Sep 2020 06:28:43 +0200 Received: from ptr-fq9pjpg9k9a4si5prqf.18120a2.ip6.access.telenet.be (ptr-fq9pjpg9k9a4si5prqf.18120a2.ip6.access.telenet.be [IPv6:2a02:1812:c3c:3a00:d31:b6d5:761e:c5a7]) (Authenticated sender: brendt@stitcher.io) by srv021.web.ichtushosting.com (Postfix) with ESMTPSA id A572420EA7; Fri, 18 Sep 2020 06:28:38 +0200 (CEST) X-MailCleaner-return_path: brendt@stitcher.io X-MailCleaner-sender_address: brendt@stitcher.io X-MailCleaner-recipients: matthewmatthew@gmail.com, internals@lists.php.net Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.80.23.2.2\)) In-Reply-To: Date: Fri, 18 Sep 2020 06:28:37 +0200 Cc: PHP internals Content-Transfer-Encoding: quoted-printable Message-ID: <92973D90-AAEF-4975-847B-5E62FEEBD1E2@stitcher.io> References: <09DE673B-71B7-4C8E-A795-900B51F8E476@stitcher.io> To: Matthew Brown X-Mailer: Apple Mail (2.3608.80.23.2.2) X-MailCleaner-TrustedIPs: Ok Subject: Re: [PHP-DEV] The case for transpiled generics From: brendt@stitcher.io (Brent Roose) Hi all To make myself clear, since I realise I used a confusing term in the = subject of my mail. What I'm proposing is runtime-erased generics, the = way Matthew describes them: PHP completely ignores them during runtime, = and wouldn't do anything with them during compile time. It's up to third = party tooling to do type checks. And I just want to point out to people = who haven't used any static analysers in PHP before: they are very_ = insightful in knowning what your code does, without running it. I don't = think there's reason to fear to not checking these types at runtime, = since static analysis truly takes care of them. Thanks Matthew for pitching in, I believe the opinion of the ones = building and maintaining the current static analysis toolset in PHP is = essential in this discussion. Kind regards Brent > On 17 Sep 2020, at 23:00, Matthew Brown = wrote: >=20 > I think the addition of runtime-erased generics would be a good thing = for the language. >=20 > I don=E2=80=99t think PHP should perform any sort of checking of = generic parameters at compile time. No other equivalent interpreter = performs those compile-time checks, and it=E2=80=99s also *very* complex = =E2=80=94 since adding support for generics in Psalm I=E2=80=99ve spent = the ensuing two years fixing many bugs and filling various holes that = have cropped up. Hack, introduced in 2014 and written by bunch of people = far smarter than me, had at least one hole in its type-checker=E2=80=99s = generics handling that was only patched last year. >=20 > PHP could develop a separate official type-checker to be used = alongside its interpreter, similar to Hack=E2=80=99s (hh_check) or = TypeScript=E2=80=99s (typescript-checker), but that=E2=80=99s an = entirely separate conversation. >=20 > =E2=80=94=E2=80=94=E2=80=94 >=20 > If this proposal happens, the documentation should make it *super* = clear that all generic types are erased at runtime. >=20 > Erased generics would not support code like this: >=20 > ``` > function filter(array $arr) : array = { > $new =3D []; > foreach ($arr as $a) { > if ($a instanceof T) { > $new[] =3D $a; > } > } > } > ``` >=20 > Instead PHP would need to support a type classname (or similar) to = allow passing generic params explicitly. >=20 > ``` > function filter(array $arr, classname = $t_class) : array { > $new =3D []; > foreach ($arr as $a) { > if ($a instanceof $t_class) { > $new[] =3D $a; > } > } > } > ``` >=20 > The implementation would also need a way of denoting covariant (pretty = common) and contravariant (very rare) generic parameters, like Hack = does. >=20 >=20 >> On Sep 17, 2020, at 7:34 AM, Brent Roose wrote: >>=20 >> =EF=BB=BFHello internals >>=20 >> Today I'd like to hear your thoughts on what might be a controversial = topic, though I think it's worth having this discussion. I want to make = the case for adding generic syntax, without actually enforing any = additional type checks at runtime. Please hear me out. >>=20 >> We've been discussing generics for years now [1][2], all without any = result. Nikita's latest attempt [3] stalled because, from what I = gathered and amongst other things, doing generic type checks at runtime = has a significant impact on performance. >>=20 >> On the other hand, static analysers have been making their rise for a = few years now. Granted: not the whole community might like this kind of = type strictness, and PHP doesn't force them to; but still projects like = PhpStorm acknowledge their significance =E2=80=94 they will add built-in = support for both psalm and PHPStan later this year [4]. Rasmus Lerdorf = also showed interest in the idea of improving PHP's static analysis = capabilities two years ago [5]. >>=20 >> That all to say that there's a significant part of the PHP community = who's interested in embracing the benefits of static analysis.=20 >>=20 >> If we look outside of our PHP bubble, we can see the same thing = happening in JavaScript: the core benefit that TypeScript adds is its = robust static analysis. Sure those developers need an extra compilation = step to transpile their code to plain old JavaScript, but it seems that = they are=E2=80=A6 fine with that? >>=20 >> I'd like to discuss a similar idea for PHP. If runtime generics = aren't possible because of performance issues, why not explore the other = option: adding generic syntax that is ignored by the interpreter, but = can be used by static analysis tools =E2=80=94 third party of built-into = PHP, that's another discussion. I realise this thought goes against the = "PHP mindset" we've been programming with for more than 20 years, but we = I think we shouldn't ignore what's happening in the PHP- and wider = progamming community: static analysis is relevant, whether you want to = use it or not, and a stricter type system is prefered by many. >>=20 >> Now I know there are alternatives we can use today. Static analysers = already support generics, using doc blocks. I'm not trying to argue that = it's impossible to achieve the same results with the toolset we have, = but rather that there's room for improvement from the developer's point = of view. History has shown that such convenience additions to PHP have = been a difficult pill to swallow for some, but on the other hand those = kind of changes _have_ been happening more and more often anyway: = property promotion, short closures, named arguments, attributes, yes = even types themselves: you can write the same working PHP program = without any of those features, and yet they have been proven so useful = and wanted over the last years. >>=20 >> As a sidenote: the idea of transpiling is already present in PHP. = Looking at constructor property promotion: a purely syntactical feature, = which is transformed to simpler PHP code at runtime. Nikita called this = principle "desugaring" in the constructor property promotion RFC [6]. >>=20 >> So here's my case for transpiled generics summarized: >>=20 >> - There's no significant runtime performance impact >> - The PHP community is already embracing static analysis >> - Transpiling has been proved to be a viable workflow, thanks to = TypeScript >> - As with all things-PHP: it's opt-in. You don't have to use the = syntax if you don't want to and you won't experience any downsides >>=20 >> So with all that being said, I'm looking forward to hearing your = thoughts.=20 >>=20 >> Kind regards >> Brent >>=20 >> [1] https://wiki.php.net/rfc/generics = =20 >> [2] https://wiki.php.net/rfc/generic-arrays = =20 >> [3] https://github.com/PHPGenerics/php-generics-rfc/issues/45 = =20 >> [4] = https://blog.jetbrains.com/phpstorm/2020/07/phpstan-and-psalm-support-comi= ng-to-phpstorm/ = =20 >> [5] https://externals.io/message/101477#101592 = =20 >> [6] https://wiki.php.net/rfc/constructor_promotion#desugaring =