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 <bi...@scriptfusion.com> 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
>

Reply via email to