Hey Bilge,
I'm not usually a resident of these discussions, but it seems like this RFC
is heading into a wrong direction. Let me explain: as it currently stands,
static properties and methods live separately from instance properties and
methods. That means a couple of limitations, namely: a static class member
can never implement an interface's contract, and hence a static class could
never be used as an instance; static class members have a separate
reflection API; static class members cannot have expression initializers;
there's no static constructor; and so on. Adding static classes
would not
solve any of the above issues, and they would still be barely useful.
To counter these issues, Kotlin has a concept of data objects
: <
https://kotlinlang.org/docs/object-declarations.html#data-objects>.
They
look like regular classes, but only one instance of a data object is
created - when it's first accessed by other code. The closest alternative
in PHP would be an enum with a single case. Unlike static classes, `data
objects` don't have any of the problems associated with static members.
They can be passed around as an instance of a class. This allows
implementing interfaces, and replacing a data object
with a regular class
instance without having to change all member access from static to
instance. They would also be able to inherit the syntax and semantics of
regular class constructors:
```
object Converter {
private array $map = new Map();
public function __construct() {
$this->map['miles to km'] = 1.6;
}
public function convert(string $type, float $value): float {
return $value * $this->map[$type];
}
}
doSomeConversion(Converter::object);
// If Converter
is ever to become a regular class, none of the related
code would require changes.
function doSomeConversion(Converter $converter) {
$result = $someUtils->convert('miles to km', 123);
}
```
That would be functionally equivalent to:
```
class Converter {
private static self $instance;
public static function instance(): self {
return self::$instance ??= new self();
}
public function convert(float $something): float {}
}
doSomeConversion(Converter::instance());
```
Of course, this is already possible, as shown in the second example. But so
is this RFC. Implementing data objects would actually bring them on-par
with regular classes, and likely cause less drama overall.
On Mon, Jun 24, 2024 at 2:14 AM Bilge <[email protected]> wrote:
> Hi Internals!
>
> I am pleased to present my first RFC: Static class
> <https://wiki.php.net/rfc/static_class>.
>
> This work is based on the previous discussion thread on this list of the
> same name, and hopefully captured all the relevant details,
> notwithstanding anything unanticipated that may present itself during
> the implementation. Let me know if you feel anything important has been
> missed. I am aware it omits to mention specifics about messages so
> emitted when runtime or compile-time errors occur, but I anticipate this
> can be hashed out in the PR, unless consensus indicates otherwise.
>
> I am aware this idea is not supported by everyone, but there seemed to
> be enough positive voices for it to be worth a shot. I'd like to get a
> better idea of where people might stand when it comes down to a vote,
> now there is a formal RFC, so we know whether it's worth completing the
> implementation, although any sentiments so proffered are of course not a
> commitment to vote any particular way and nobody should feel compelled
> to speak to that unless comfortable. Looking forward to feedback!
>
> Cheers,
> Bilge
>