> > to me this closes extensibility in a hard way. > > This is not necessarily true, we have `final` in PHP which does exactly > that, but `sealed` can still allow for extensibility, just from a different > point, e.g: >
`final` has the same issue to me: it's a feature of the language that would be better enforced by a static analyzer instead of a runtime check. This would work for me: #[Sealed(A::class, B::class, ...)] interface Foo {...} Then, nothing in php-core but a rule in SA tools to check that the semantics of the attribute are respected (or a custom exception to the rule when a user really wants to ignore the attribute for a specific class, being on their own then). Note that for `final` this is already common practice - using the `@final` annotation to express the intent that a class is final but still allow e.g. to generate a lazy proxy or a mock class (or any other need authors cannot anticipate). > Considering the `Option`/`Some`/`None` example above, given `Option`, now > you are sure that it's either an instance of `Some` or `None`, where > previously, a third type could exist. > > Authors previously got around this issue by adding methods on `Option` > such as `isSome()`/`isNone()`/`isSuccess()`/`isFailure()` .. etc > Or "instanceof Option|Some|None", which achieves something very similar to me. This relates to the paragraph about composite types in the RFC: most of the problems you describe for them can be solved in practice by introducing an abstract (@internal) class. Please note that I'm making these criticisms in a constructive mindset. I do appreciate that there is an RFC about sealed classes and that we can discuss if and how we want them in PHP. Right now, I'm not convinced we should add them and I'm trying to articulate why, that's all :) Nicolas