On Wed, 8 Feb 2023 at 00:13, Sergii Shymko <ser...@shymko.net> wrote:

> I think, typed variables would be a necessary prerequisite for typed
> arrays and eventually generics.
> If my understanding is correct, the primary concern there is performance
> overhead of iterating items for type checking.
> With typed variables, type checking is done at assignment and passing
> typed array around becomes lightweight.
> It would be enough to type check against a known array item type without
> iterating over items.
>
> For example:
> function do_something(array<string> $strings) {
>     ...
> }
> array<string> $names = ['John', 'Jane', 'Jake'];  // items are type
> checked similar to variadic argument unpacking
> sort($names);
> do_something($names);  // lightweight type check as for scalar types



This is probably more complicated to implement than you're imagining.

Firstly, there is a key distinction between *variables* and *values*: when
you say do_something($names), the receiving code in do_something doesn't
know that the argument it was given is the variable $names, with type
array<string>; it just receives the value ['John', 'Jane', 'Jake'].

That leads to another distinction: the variable has a single type
*constraint* ("must always point to a value matching this type"), but the
value has multiple pieces of type *information* ("has been checked as
meeting these different constraints"). Both can also be deduced using the
relationships between types. For example:

function do_something(array<string> $strings) {
    ...
}
function filter_non_strings(array<mixed> $items): array<string> {
    ...
}
array<string|int> $mixed_list = ['John', 42, 'Jane'];
$mixed_list = filter_non_strings($mixed_list);
// when calling filter_non_strings, we know that the value matches
array<string|int>, so can deduce that it matches array<mixed> as well
// when assigning the result back to $mixed_list, we know (from the return
type check) that it matches array<string>, so can deduce that it matches
array<string|int> as well

do_something($mixed_list);
// since the value hasn't changed since it was returned, it still matches
array<string>, even though the variable doesn't have that constraint

sort($mixed_list);
// for this call to succeed, we need to know that the variable is an array;
we can deduce that from knowing it matches array<string> or knowing that it
matches array<string|int>
// as a minimum, we need to assert that after modifying it by reference, it
still matches array<string|int>, as required by $mixed_list
// but do we also still know that it matches array<string>?

It's all probably doable, but I think it's the other way around from your
initial statement: working out how to cache type checks would be a
pre-requisite for implementing local variable types.

Regards,
-- 
Rowan Tommins
[IMSoP]

Reply via email to