On Mon, Aug 19, 2024, at 19:08, Derick Rethans wrote: > Hi! > > Arnaud, Larry, and I have been working on an article describing the > state of generics and collections, and related "experiments". > > You can find this article on the PHP Foundation's Blog: > https://thephp.foundation/blog/2024/08/19/state-of-generics-and-collections/ > > cheers, > Derick >
As an experiment, awhile ago, I went a different route for reified generics by 'hacking' type aliases (which I was also experimenting with). Such that a generic becomes compiled into a concrete implementation with a dangling type alias: class Box<T> { function __construct(T $thing) {} } is essentially compiled to class Box { use alias __Box_T => ???; function __construct(__Box_T $thing) {} } This just gets a T type alias (empty-ish, with a mangled name) that gets filled in during runtime (every instance gets its own type alias table, and uses that along with the file alias table). There shouldn't be any performance impact this way (or at least, as bad as using type aliases, in general; which is also an oft-requested feature). Thus, when you create a new Box<int> it just fills in that type alias for T as int. Nesting still works too Box<Box<int>> is just an int type alias on the inner Box and the outer Box alias is just Box. Type-checking basically works just like it does today (IIRC, Box<int> literally got stored as "Box<int>" for fast checking), and reflection just looks up the type aliases and unmangles them -- though I know for certain I never finished reflection and got bogged down in GC shenanigans. There were probably some serious cons in that approach, but I ran out of free time to investigate. If you are doing experiments, it is probably worth looking into. FYI though, people seemed really turned off by file-level type aliases (at least exposed to user-land, so I never actually pursued it). — Rob