Re: Static class

From: Date: Sun, 16 Jun 2024 09:49:49 +0000
Subject: Re: Static class
References: 1 2 3  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message


On Sun, Jun 16, 2024, at 11:17, Bilge wrote:
> Let's start getting specific so we can make some progress.
> 
> The goals of this RFC are fairly straightforward:
>  • Introduce the static keyword at the class level to preclude the need to
> create a private constructor. That is, __construct would be invalid in a static class.
>  • Prohibit instantiation of a static class with a language-level error.
>  • Prohibit declaration of instance members in a static class with a language-level error.
> However, as ever, there's a devil in the details. In particular, we need to consider the
> following:
> 
> 
>   1. Since a "static class" implies all members are static, should we still allow
> explicit static method declarations with the static keyword?
> 

To keep it inline with readonly and abstract. I would look to those and follow their rules. 

> 
>   2. Should static imply final?
>     2a. If yes, should final still be allowed to be explicitly declared, despite
> being implied?
> 

I would allow it, though emit a warning that it’s unnecessary. That’s what I would expect from a
compiled language, anyway. 

> 
>   3. Should a "static class" prohibit inheritance?
> 

I would think it should be allowed. This is one of the most annoying things about static classes in
C#. That being said, PHP has traits, so static classes could theoretically use traits to provide
inheritance-like behavior. Can traits be marked static, or just classes?

> 
>   4. Should a "static class" permit state?
> 

Here’s the thing, there are still ways to get state even if you disallow it (create a function
called getState() that has an internal static array). Using state in a static class is a code smell,
for sure. However, constants should be allowed and even those are quite limited in what values they
can hold. Until that gets cleared up, we should perhaps allow variables so complex constants can
exist (implementing the construction of them, however, should be left as an exercise for the
developer).

> 
>   5. Should traits be permitted in a static class?
> 

I hope so. Traits are some of the most abused super powers of PHP. 

> 
>   6. Which magic methods (if any) should be valid in a static class?
> 

Are magic methods allowed in a static context? If so, only those should be implementable. 

> Based on my current understanding, I would propose the following answers to these questions:
> 
> 
>   1. In order to make upgrading simple and keep method intentions clear, static
> should not only be valid but also required on each method declaration, as usual for static methods.
>   2. Inheritance doesn't make much sense in a purely static context, despite the fact that
> PHP has a static resolution operator; I often find this is an anti-pattern. In any case, this is a
> non-BC issue if we lock down inheritance for now and later decide to open it up. Disabling
> inheritance also is in-line with the C# implementation of the same.
>     2a. Since under this proposal, final is implied, it should not be necessary
> (or allowed) to be specified. Upgrading would be simply a case of replacing final with
> static in-place.
>   3. As already mentioned, inheritance in a purely static context doesn't make much sense,
> and it's a non-BC break to prohibit it and later enable it. This decision is also in-line with
> the C# implementation.
>   4. Perhaps the most contentious decision, we could disable state and later enable it if there
> is a need, without BC. I personally cannot think of a time when I needed state in a static class.
> That said, I do not agree with disabling state within the language. In case someone is relying on
> static state in such a class, upgrading would be impossible; they would instead have to avoid
> marking the class as static, which defeats the purpose of this RFC. I believe we should support
> state, and if someone dislikes static state, they should enforce that with a code style rule in
> their project; this is not something that should be prohibited by the language itself as
> "regular" classes already allow this.
>   5. Provided a trait follows the rules of the static class (i.e. all members are static), it
> seems to me this should be allowed, though I have little use for it myself.
>   6. Given there are many magic methods, this topic probably deserves a separate discussion; it
> is not something I have spent a lot of time on thus far so it is just included for visibility at
> this time.
> 
> If there are any strongly dissenting opinions on any of these points, or any significant points
> I may have missed, please share. Otherwise, I would be happy to draw up and RFC along these lines
> (notwithstanding I have no RFC karma at present), followed by an implementation once all outstanding
> questions are answered.
> 
> 
> Cheers,
> Bilge
> 
> 
> On 15/06/2024 14:53, Rowan Tommins [IMSoP] wrote:
>> On 15/06/2024 12:16, Bilge wrote:
>>> 
>>> I want to introduce the static keyword at the class declaration level.
>>> That is, the following would be valid: static class Foo {}.
>> 
>> 
>> This has been proposed before, and was rejected at vote. It was nearly 10 years ago, so
>> opinions may have changed, but it would be worth reading through the prior discussion to anticipate
>> or counter the objections raised, and avoid re-treading the same ground. 
>> 
>> - RFC: https://wiki.php.net/rfc/abstract_final_class
>> 
>> - Pre-vote discussion threads: https://externals.io/message/79211 and https://externals.io/message/79338 
>> - Final vote thread: https://externals.io/message/79601 
>> 
>> Searching my list archive, I find that it came up again a few months ago, which I'd
>> entirely forgotten: https://externals.io/message/121717 
>> 
>> Slightly tangential, but some of the same discussion also came up on these rather lengthy
>> threads about "static class constructors": https://externals.io/message/84602 and https://externals.io/message/85779 
>> 
>> 
>> Regards,
> 
> 

— Rob


Thread (32 messages)

« previous php.internals (#123627) next »