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 <matthewmatt...@gmail.com> wrote: > > I think the addition of runtime-erased generics would be a good thing for the > language. > > I don’t 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’s also *very* complex — since adding support for generics in > Psalm I’ve 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’s > generics handling that was only patched last year. > > PHP could develop a separate official type-checker to be used alongside its > interpreter, similar to Hack’s (hh_check) or TypeScript’s > (typescript-checker), but that’s an entirely separate conversation. > > ——— > > If this proposal happens, the documentation should make it *super* clear that > all generic types are erased at runtime. > > Erased generics would not support code like this: > > ``` > function filter<T of object>(array<int, object> $arr) : array<int, T> { > $new = []; > foreach ($arr as $a) { > if ($a instanceof T) { > $new[] = $a; > } > } > } > ``` > > Instead PHP would need to support a type classname<T> (or similar) to allow > passing generic params explicitly. > > ``` > function filter<T of object>(array<int, object> $arr, classname<T> $t_class) > : array<int, T> { > $new = []; > foreach ($arr as $a) { > if ($a instanceof $t_class) { > $new[] = $a; > } > } > } > ``` > > The implementation would also need a way of denoting covariant (pretty > common) and contravariant (very rare) generic parameters, like Hack does. > > >> On Sep 17, 2020, at 7:34 AM, Brent Roose <bre...@stitcher.io> wrote: >> >> Hello internals >> >> 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. >> >> 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. >> >> 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 — 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]. >> >> That all to say that there's a significant part of the PHP community who's >> interested in embracing the benefits of static analysis. >> >> 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… fine with >> that? >> >> 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 — 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. >> >> 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. >> >> 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]. >> >> So here's my case for transpiled generics summarized: >> >> - 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 >> >> So with all that being said, I'm looking forward to hearing your thoughts. >> >> Kind regards >> Brent >> >> [1] https://wiki.php.net/rfc/generics <https://wiki.php.net/rfc/generics> >> [2] https://wiki.php.net/rfc/generic-arrays >> <https://wiki.php.net/rfc/generic-arrays> >> [3] https://github.com/PHPGenerics/php-generics-rfc/issues/45 >> <https://github.com/PHPGenerics/php-generics-rfc/issues/45> >> [4] >> https://blog.jetbrains.com/phpstorm/2020/07/phpstan-and-psalm-support-coming-to-phpstorm/ >> >> <https://blog.jetbrains.com/phpstorm/2020/07/phpstan-and-psalm-support-coming-to-phpstorm/> >> >> [5] https://externals.io/message/101477#101592 >> <https://externals.io/message/101477#101592> >> [6] https://wiki.php.net/rfc/constructor_promotion#desugaring >> <https://wiki.php.net/rfc/constructor_promotion#desugaring> -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php