Re: [PHP-DEV] [RFC] Typed array declarations

[email protected] ("Larry Garfield") Mon, 20 Jul 2026 10:20:38 -0500
Newsgroups php.internals
Message-ID <[email protected]>
On Fri, Jul 17, 2026, at 6:28 AM, Rob Landers wrote:
> On Fri, Jul 17, 2026, at 12:41, Wendell Adriel wrote:

> Hi Wendell,
>
> Thanks for updating the RFC.
>
> My largest concern is that this proposal substantially overlaps with=20
> the reified generics RFC, which is being held until after the current=20
> code freeze in late August or early September at the earliest.
>
> In particular, both proposals need to answer many of the same question=
s=20
> around parameterized types, variance, Reflection, runtime enforcement,=20
> inference, and type identity. I think we should avoid committing PHP t=
o=20
> a separate set of array-specific rules before the broader generics=20
> proposal has been discussed. Otherwise, we risk either constraining th=
e=20
> generics design or ending up with two parameterization models that=20
> behave differently.
>
> My second concern is the proposed variance model. It is extremely=20
> complex for a mutable built-in collection. Collections are normally=20
> invariant unless their API clearly separates reading from writing. The=20
> generics RFC follows that model: generic parameters are invariant by=20
> default, and covariance or contravariance is permitted only where thei=
r=20
> usage can be proven safe.
>
> Here, an `array<Dog>` is treated as compatible with `array<Animal>`=20
> only at selected by-value boundaries, based on PHP's copy-on-write=20
> separation. It then becomes invariant for writable aliases and require=
s=20
> additional rules for shared references.
>
> That does not appear to establish a normal subtype relationship. It=20
> establishes context-dependent boundary compatibility whose soundness=20
> depends on engine-level array separation and reference behavior. I=20
> think that will be challenging for users to understand and difficult=20
> for the engine to enforce consistently.
>
> Making parameterized arrays invariant would be substantially simpler:
>
> array<int, Dog> !=3D=3D array<int, Animal>
>
> If covariance is desirable, I think it should come from a separate=20
> read-only collection or interface rather than from mutable arrays.
>
> My third concern is the one-argument syntax:
>
> array<TValue>
>
> This implicitly means:
>
> array<int, TValue>
>
> That is surprising. It is not a general array of values because string=20
> keys are rejected, but it is not a list either because the integer key=
s=20
> need not be contiguous or zero-based. I would expect `array<TValue>` t=
o=20
> constrain only the value type, with the key type remaining=20
> `int|string`. A future `list<TValue>` could express the more=20
> restrictive numeric-keyed form.
>
> Lastly, I am concerned about repeated runtime validation. Since=20
> ordinary arrays do not retain a trusted element-type identity, an=20
> untyped boundary loses any information established by an earlier check:
>
> function foo(array<Bar> $arr): int
> {
>     $acc =3D 0;
>
>     foreach ($arr as $bar) {
>         $acc +=3D $bar->count;
>     }
>
>     return $acc;
> }
>
> function bar(array $arr): int
> {
>     return foo($arr);
> }
>
> $arr =3D get_super_huge_array();
> echo bar($arr);
>
> At the call to foo(), PHP must recursively validate the entire array=20
> again, even if the same array was previously checked elsewhere. For=20
> large or nested arrays, this makes a type declaration potentially=20
> introduce an O(n) or recursive O(n) cost at every typed boundary.
>
> This is another reason I think typed arrays should be considered=20
> together with the wider generics design. A broader design may be able=20
> to provide type identity, inference, specialized collection types, or=20
> another mechanism that avoids repeatedly rediscovering the element typ=
e=20
> by traversing the value.
>
> I would strongly prefer that this RFC wait until the reified generics=20
> RFC has been discussed, or at minimum limit itself to syntax and=20
> Reflection experimentation without committing to independent variance=20
> and runtime semantics.
>
> =E2=80=94 Rob

I am opposed to this RFC, for all the reasons Rob mentioned.  Moreover, =
I don't believe the issues can be resolved by just waiting for the reifi=
ed generics RFC (which I really hope passes).  The core issue is that PH=
P arrays are an over-broad data structure, and we need to have a hard, t=
ype-based (not just implied by generics) distinction between lists/seque=
nces, sets, and dictionaries/maps, the same way most languages do.

There are a few ways that could be done: 3 generic objects (a la Kotlin,=
 my preferred approach), 3 generic objects with extension functions (ass=
uming we can get those), 3 new core data types with extension functions =
(very hard to implement as I understand it), etc. =20

But tacking it onto the already-dangerously-overloaded array mega-type i=
s the wrong approach.

--Larry Garfield