Hey Nicolas,

Am 15.05.2026 um 14:09 schrieb Nicolas Grekas <[email protected]>:

I'd like to put a syntax proposal on the table that may address Rowan's 
concern, and that also addresses something I'm worried about independently: the 
migration path for existing libraries.

How does a library that uses @template docblocks today migrate to native syntax 
without forcing a BC break on its consumers? Multiplied across the libraries 
out there, this is a major point of tension for the ecosystem we need to 
anticipate.
Existing @template annotations were adoptable gradually *because* they're 
invisible to the engine.
Native <T> syntax, as the RFC proposes it, doesn't have that property: a 
library cannot adopt it without bumping its minimum PHP version and pulling all 
its consumers with it.

We've solved this exact problem once before for attributes. The #[...] syntax 
was deliberately designed so older PHP versions would parse it as a # line 
comment, which is what made the adoption across the ecosystem so smooth.
The same trick is available for generics if we pick the right delimiter. 
Concretely, write #<...> everywhere <...> appears in the current RFC: 
declarations, inheritance clauses, type uses in signatures, call-site 
arguments. One syntax, used uniformly.

Three benefits, beyond the migration story:

1. FC for free. A library can adopt native generics in source today and 
continue running on older PHP versions, because the engine just sees comments. 
No need to coordinate with the min-PHP bump.
2. The turbofish goes away. No need to disambiguate < from less-than 
comparison. With #<...>, the token is unique and unambiguous everywhere: at 
declaration, use, and call site. We get to drop a whole grammar mechanism 
rather than introduce one.
3. Rowan's concern is addressed typographically. Anything inside #<...> is the 
erased, SA-enforced layer; everything outside follows the engine's normal 
runtime-checked rules.

For codebases that want to adopt native generics while still supporting earlier 
PHP versions, #<...> would need to sit at the end of a line so older parsers 
consume it as a # line comment. Code targeting only generics-aware PHP can 
write it inline. The line-break constraint is a transitional code-style cost, 
not a permanent property of the syntax, and it's bounded by however long 
libraries support pre-generics versions.

WDYT? I expect Seifeddine has good reasons to prefer the current syntax. I'd 
like to put this on the table because the FC story it unlocks, combined with 
the turbofish simplification, might be worth the trade-off and might help 
gather a broader consensus.

Cheers,
Nicolas

I'd like to ask you: do we need to migrate this quickly?

For attributes the #[] syntax was chosen, because it was actually on the table 
in the first place - we needed a delimiter - and by chance it's something 
generally on its dedicated line of code - the primary target being classes and 
methods.

Types? They're neither generally suffixed to a line (except for classes with 
many extends/implements and for classes without any as well as return types). 
Everything else is in the middle of the line.

It doesn't really fit here. And also it has a bit of ugliness. Would you really 
want to use #<...> long-term? I wouldn't compromise long-term syntax for 
short-term benefits.

Also, again, do we need people to switch over to the language provided generics 
right now? As far as I see, most libraries and frameworks support a 2~3 years 
old PHP version on their master version (I.e. what becomes their next major).
People can *still* use @template for now. It's not a fundamental ability which 
wouldn't be there without this feature.
Unlike attributes, which were more or less not doable without manual 
hand-rolled docblock parsing (as opposed to a handful static analysis tools 
which handle docblock parsing).

Another benefit of it would probably be, if we were to introduce reified 
generics over the next few versions of PHP, the blast radius of 
previously-unverified types now becoming checked is much smaller than when 
every framework already had first-class support for it.

So, having a slower adoption of language-generics could actually be a feature 
rather than an annoyance.

Bob

Reply via email to