On Friday, May 15th, 2026 at 7:13 AM, Nicolas Grekas 
<[email protected]> wrote:

> 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
> 


How would generic types be expressed in parameters and return types?

```php
// Current RFC:
function DoStuff<T>(myParam: T, otherParam: int): T {
    // ...
}
```

Existing PHP versions will have no clue what `T` is. Only one of the uses of 
`T` here is inside `<...>`. Wrapping the others in `#<...>` would be 
syntactically incoherent (and rather ugly, I think). But the only alternative 
that comes to mind is:

```php
function DoStuff#<T>(myParam#: T, otherParam: int)#: T {}

// which would have to look like this in projects continuing to support prior 
PHP versions:
function DoStuff#<T>
(
    myParam#: T
    , otherParam: int // bizarre comma placement
)#: T
{
    // ...
}
```

Syntax parsing would, I suspect, be rather more complicated, unless you 
required the type to be placed in parentheses, which would only make the syntax 
even less appealing:


```php
function DoStuff#<T>(myParam#:(T), otherParam: int)#:(T) {}

// and in projects continuing to support prior PHP versions:
function DoStuff#<T>
(
    myParam#:(T)
    , otherParam: int
)#:(T)
{
    // ...
}
```

If not for those (major, in my view) syntactical issues, I might've been on 
board with the idea. (Just to be clear, I don't have voting privileges.) 
Conceptually, it feels proper to use "#" again for structured metadata that has 
*some* engine-enforced functionality, but which is primarily targeted at 
(static analysis) developer tools. But once one realizes that generics will be 
used in places outside of `<...>`, I think the viability of the syntax 
crumbles, and I'd rather just have the original proposal.

Reply via email to