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

Reply via email to