On Tue, Aug 5, 2025, at 08:19, Rob Landers wrote: > > On Mon, Aug 4, 2025, at 22:49, Levi Morrison wrote: >> On Mon, Aug 4, 2025 at 9:26 AM Larry Garfield <la...@garfieldtech.com> wrote: >> > >> > Hi folks. I recently wrote a blog post on behalf of the PHP Foundation >> > about some work Gina has been doing regarding generics. It's a follow-up >> > to last year's post on a similar topic. We are especially looking for >> > feedback from the Internals crew, and voters in particular, on whether or >> > not to proceed. >> > >> > https://thephp.foundation/blog/2025/08/05/compile-generics/ >> > >> > Wearing my Internals/voter hat, my stance is a very strong "yes please!" >> > >> > -- >> > Larry Garfield >> > la...@garfieldtech.com >> >> I played with a few iterations of Gina's work. My opinion at that time >> was that there are too many restrictions to be very useful. Based on >> those evaluations, I would not consider it to be "80% of the >> benefit.". With that said, maybe Gina has removed some of the >> restrictions. Based on the article it , but I'll commit to trying it >> out again. >> >> One thing the article says we're missing and that we we definitely >> need is unions, or at the very least the union with null. Nullable >> types are everywhere, and even in your interfaces it's going to show >> up. For instance, if we had interfaces for Set, Map, etc, there are >> going to be operations which return nullable values. Sure, exceptions >> can be thrown in some cases but not all of them. For instance, if you >> are building a caching data structure, throwing an exceptions on a >> cache miss would be very bad for performance*. You can separate it >> into has + get, but this has two lookups which is not desirable for >> performance. You can return a "tuple" like `[found, $value]` where >> `$value` may be null, but this loses even more type safety, and isn't >> a very common pattern in PHP. You really want `T|null`. >> >> There are probably other "edges" that are important and should be >> handled in this first pass, but missing nullable types is not a small >> thing. >> >> * We'll get a mini-optimization in PHP 8.5 for making the exception >> object faster to construct, but it doesn't speed up the backtrace, >> which is where most of the performance cost comes from in practice. If >> you are benchmarking this, make sure to include cases where your stack >> is a few dozen frames deep. I work for an observability company for my >> day job, and it is insanely normal for there to be 10+ frames, and >> still fairly common to be 30+ frames. Think about routing, frameworks, >> middleware, helper functions, libraries and abstractions, etc. If you >> use middleware in particular, expect 50+ frames to be normal. >> > > I have a few different ideas for unions/intersections, but to implement them > now would be refactoring for the sake of refactoring. There would be no > benefit to implement any of it now. > > Earlier this year I tried interning types, so that type checking could be > simple pointer equality. From there, I implemented a tri, such that > intersections and unions were very fast to check. > > The result is that it was virtually useless with today’s php, except for the > most pathological cases. PHP doesn’t do much type checking — currently. > > In any case, the changes required to pull it off (not counting opcache) were > huge. If we were to run into the pathological cases more often (such as with > runtime generics), it might be worth it. > > All that being said, we are talking about *compile-time* generics. If there > is a time to be less efficient, it is during compilation, which generally > happens once (esp with opcache). Further, pathological type checking is quite > rare in codebases (most types are relatively simple without deep hierarchical > intersections and unions), so I assume it will be fine to enable them. > > — Rob
It’s also worth pointing out that nullable or a union of null and another type is technically just one type with the nullable bit set. So, I suspect nullable types will still obey the “single type” rules proposed here. — Rob