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

Reply via email to