On 16 May 2026 22:32:30 BST, Seifeddine Gmati <[email protected]>
wrote:
Hi Rowan,
The parts this RFC enforces (generic declaration syntax, type-parameter
resolution, inheritance arity, bound conformance, parametric LSP, variance
soundness, and turbofish arity) are exactly where static analysis tools
currently disagree most.
Thanks. It sounds like there's a few different things:
Some differences are directly resolved by the proposal; most notably,
everything around syntax and keyword naming, since this would be fully
standardised in PHP.
In some cases, the problem remains, but the RFC gives the *user* power
to remove the ambiguity; e.g. inference has no one right answer, and
explicit call-site syntax means users don't have to rely as much on how
tools approach it. I can see why that is hard to do without new and
concise syntax.
In other cases, it sounds like the correct answer is actually an
established fact of type theory - e.g. the behaviour of covariance and
diamond inheritance. In those cases, the value of the RFC is more
subtle, because all it's doing is lending extra urgency to fixing
something that everyone should agree is a bug.
Regarding your suggestion to include all unchecked type information in one
place: adding a syntactic tier that PHP parses but ignores would be a new
architectural pattern.
That is exactly my concern with your proposal!
Behind the jargon, I think the long list of things enforced and not
enforced boils down to:
- the minimum bound of a type parameter is propagated automatically as
the run-time type
- the behaviour of extending a generic class or implementing a generic
interface is enforced
- the behaviour of passing a value to a generic function parameter,
return type, etc, is completely unenforced; the language just provides
syntax for SA tools to hang their own semantics onto
In many cases, none of the enforced parts actually apply, so this:
function<T> wrap(T $item): SomeDataStructure<T>
would be entirely equivalent, as far as PHP is concerned, to this:
function wrap($item): SomeDataStructure
All of the rest is just "a syntactic tier that PHP parses but ignores".
>Beyond that, it creates its own coordination
>problem. If `~~lowercase-string` is parsed by PHP but interpreted by
tools,
>any disagreement on semantics (e.g., whether `""` is lowercase,
whether the
>rule is ASCII or multibyte, whether numeric strings count) remains. PHP
>would host syntax it doesn't understand, and the ecosystem would still
lack
>a governance mechanism for those semantics. making it truly 100% useless.
If the implementation was actually enforced by PHP, it would not use the
extra syntax.
If the implementation was *not* enforced by PHP, tools would have to
choose how to implement it; either individually, or through collective
decision-making between tools. It would make no difference whether PHP
spelled the type as "lowercase-string" or "string~~lowercase".
The biggest advantage I see is the speed of innovation - I've seen ideas
for new pseudo-types floated on this list, or on social media, and an
implementation available in tools within days or weeks. Users can then
start using it immediately.
A full implementation in the core language would wait for the next
annual release; and then for users to reach that level as their minimum
supported.
I thought tools might welcome a way to move away from docblock-parsing
without giving up that ability to innovate new features.
On the visibility of type parameters like `TNode`: it's true they can look
like concrete types at use sites. However, this is consistent with
languages like Java, Rust, and TypeScript. Conventions like single
uppercase letters or PascalCase (e.g. `TKey`, `TNode`) are already
well-established in the PHP ecosystem through `@template`. Native syntax
promotes these established signals into the language.
I wasn't making any comment about how type parameters are spelled. I was
responding specifically to this sentence in your previous e-mail:
> But the same argument applies to `<...>`: anything in angle brackets
> is the generic type layer, anything outside is the runtime-checked
> layer.
I was simply pointing out that some things in the "generic type layer"
are not marked by angle brackets, so in the syntax proposed by the RFC,
there is no visual signal that these are unenforced types.
Regards,
--
Rowan Tommins
[IMSoP]