On 4 June 2026 11:58:46 BST, "Ondřej Mirtes" <[email protected]> wrote:
> On 4. 6. 2026 at 12:29:42, Ondřej Mirtes <[email protected]> wrote:
>
>> ’d also like to point out a few places in currently shipping PHP version
>> where you can put types in native syntax and they are not checked at
>> runtime, meaning completely wrong and non-existent types are silently being
>> accepted or skipped.
>>
>
>I just remembered one more place: attributes.
Interestingly, all of these examples effectively make the *opposite* check to
what Seifeddine is proposing: the *name* is unchecked, but the *value* compared
to it is always rejected as not matching.
In "function foo(Nonesuch $x) {}", there is no complaint that "Nonesuch" is not
a valid class, but the function can't be called because no parameter matches.
In the proposed "function foo(Container<Nonesuch> $x)", the bounds checking
will require Nonesuch to exist, but the function can be called with any
instance of Collection. The function would be callable even if an instance of
Nonesuch was impossible to create (an interface with no implementations, or a
final private constructor, etc).
None of your examples breaks the invariant "if I mark a value as requiring a
particular type, I can be sure that reading that value will give me a value of
that type".
The only marginal case would be parameters to attributes, which can be read
through reflection without running the constructor, and therefore without
validating the types specified in that constructor. But that's in keeping with
the power of reflection to bypass the language's normal invariants, e.g.
newInstanceWithoutConstructor, setAccessible, etc
So I do think what Seifeddine is proposing is unprecedented in that sense.
Rowan Tommins
[IMSoP]