Hello Internals,
I'm sending this email to open discussion about sealed classes, interfaces, and traits feature for PHP 8.1.
I have create a Draft RFC here: https://wiki.php.net/rfc/sealed_classes
A major concern for few people have been the syntax, in which it
introduces 2 new keywords into the languages, therefor, i have added a
section about alternative syntax which could be used to avoid this
problem.
Regards,
Saif.
Note: I'm sending this email again using a different mail client as the previous one ended up in spam folder for most people
Hi Saif
Hello Internals,
I'm sending this email to open discussion about sealed classes, interfaces, and traits feature for PHP 8.1.
I have create a Draft RFC here: https://wiki.php.net/rfc/sealed_classes
A major concern for few people have been the syntax, in which it
introduces 2 new keywords into the languages, therefor, i have added a
section about alternative syntax which could be used to avoid this
problem.
As mentioned off-list, I think there's some overlap with ADTs.
https://wiki.php.net/rfc/tagged_unions
There are two major motivations of sealed I can think of:
- Usage in libraries for classes that can't be final because they're
extended by other internal classes. This prevents them from being
extended in user land and used in unintended ways, which reduces risks
of breaking changes. - For types have a fixed number of subtypes. This makes it possible
to handle a value by type and knowing that you've handled all possible
cases (exhaustiveness checks). Good examples are Option
(https://doc.rust-lang.org/std/option/enum.Option.html) or Result
(https://doc.rust-lang.org/std/result/enum.Result.html).
It could even be argued that 1 and 2 are the same. Enums/ADTs
essentially try to solve the same problem. This example is taken from
the RFC and rewritten as an enum:
enum Shape {
case Circle;
case Square;
case Rectangle;
}
Obviously this is the simplest case, but enums/ADTs allow adding
arbitrary data to each case and arbitrary behavior to the enum itself.
This approach differs from sealed in a few ways:
- Sealed allows (or requires in terms of autoloading) separating
subtypes into multiple files - The subclasses of sealed classes are allowed to have diverging APIs,
while methods in enums are currently only allowed on the enum itself.
This could be changed but feedback from the enum RFC has shown this is
not desired by most people. - Sealed could be used for existing classes without breaking the API too much.
- The syntax for enums is much more concise
- For cases with no data enums will create a singleton, while sealed
will require manually managing a singleton or creating an instance for
each value (e.g. new Option\None).
There's probably more, these are just off the top of my head. This
begs a few questions:
- Are these approaches different enough to justify both of them?
- If not, which is the preferable approach?
Ilija