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

Reply via email to