Hi Rowan,

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

Sharper than it looks. The substitution conflict has existed in PHP all
along, just in an indirect form:

```php
interface A1 extends Box<A> {}  // via @extends docblock
interface B1 extends Box<B> {}  // via @extends docblock
class C implements A1, B1 {}    // legal PHP, conflicting substituted
prototypes
```

Structurally identical to `class C implements Box<A>, Box<B>` from the
substitution view. SA tools should have caught this years ago, but they
didn't. I discovered the bug in Mago while writing the RFC. The direct form
is a compile error today (same-interface-twice), so tools never had a
forcing function to consider the substituted-conflict case, and the
indirect form slipped through. Native generics enable the direct form
possible, which forces the diamond-merge check into the engine, and that
machinery consequently covers the indirect form as a side effect.

> Behind the jargon, [...] All of the rest is just "a syntactic tier that
PHP parses but ignores".

Two pieces missing from that framing:

Reflection metadata. The pre-erasure form is exposed as introspectable
data. Frameworks, DI containers, ORMs, serializers can read generic
information directly from the engine rather than reparsing source. It's
first-class structured data that the language exposes.

The bound-as-runtime-type substitution. `class UserCollection extends
Collection<User>` substitutes T = User into every T-typed parameter and
return; those positions become User-typed at runtime, enforced by the
engine. That's real type-checking work.

> The biggest advantage I see is the speed of innovation [...]

The `~~Type` proposal raises two questions I don't see clean answers to:

1. *Lexical grammar inside `~~`?* Whitespace breaks conditional types
(`$var is Foo ? A : B`). `$` breaks variable-using expressions. `{` breaks
array shapes. `<` breaks generics. Every plausible stopping rule breaks a
class of type expressions SA tools currently support.

2. *AST shape?* Either an opaque string (tools still parse it themselves,
still disagree, gain over docblocks is just location) or structured (PHP
has committed to an AST for type expressions it doesn't enforce, which is
the architectural pattern you wanted to avoid).

The speed advantage of docblocks comes from PHP not parsing them at all.
Moving syntax into the language reduces that velocity regardless of whether
PHP enforces semantics. The RFC's trade-off is to move the *enforceable*
parts into the standard and leave the *innovation* parts in docblocks.
Future RFCs will incrementally move what's stable enough to standardize,
the docblock channel stays open for fast iteration.

> I was simply pointing out that some things in the "generic type layer"
are not marked by angle brackets [...]

Fair, I was answering a different question. At use sites a parameter `TNode
$from` doesn't carry an indicator that `TNode` is a type parameter. That's
true of every generic-supporting language; conventions (uppercase-first,
T-prefix) emerge to signal it, and the PHP ecosystem already follows them
through `@template`. But you're right that the syntactic marker is at the
declaration, not at every use.

Cheers,
Seifeddine.

Reply via email to