Hi Rob,

On Mon, Aug 19, 2024 at 7:51 PM Rob Landers <rob@bottled.codes> wrote:

> > Invariance would make arrays very difficult to adopt, as a library can not 
> > start type hinting generic arrays without breaking user code, and users can 
> > not pass generic arrays to libraries until they start using generic arrays 
> > type declarations.
>
> This seems like a strawman argument, to a degree. In other words, it seems 
> like you could combine static arrays and fluid arrays to accomplish what you 
> are seeking to do. In other words, use static arrays but allow casting to 
> treat it as "fluid."
>
> In other words, simply cast to get your example to compile:
>
> function f(array<int> $a) {}
> function g(array $a) {}
>
> $a = (array<int>) [1]; // array unless cast
>
> f($a); // ok
> g((array)$a); // ok
>
> And the other way:
>
> function f(array<int> $a) {}
> function g(array $a) {}
>
> $a = [1];
>
> f((array<int>)$a); // ok, type check done during cast
> g($a); // ok

There is potential for breaking changes in both of your examples:

If f() is a library function that used to be declared as `f(array
$a)`, then changing its declaration to `f(array<int> $a)` is a
breaking change in the Static Arrays flavour, as it would break
library users until they change their code to add casts.

Similarly, the following code would break (when calling g()) if h()
was changed to return an array<int>:

function h(): array {}
function g(array $a);

$a = h();
g($a);

Casting would allow users to pass generic arrays to libraries that
don't support generics yet, but that's expensive as it requires a
copy.

Best Regards,
Arnaud

Reply via email to