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