> On Jun 16, 2024, at 5:17 AM, Bilge <bi...@scriptfusion.com> 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:
> 

To start, any limitations imposed on these new static classes that current 
classes can do that are not intrinsically linked to their "staticness" would 
result in developers grudgingly writing a class "statically" that is not 
declared as static. Imposing restrictions on features that developers use in 
the wild would certainly cause them to consider the feature to be dubiously 
excluded. 

Not supporting all features used in the wild would result in developers not 
being able to use static classes for new and/or refactored code if they believe 
they need those excluded features. This would stop developers from signaling 
their intent to readers of their code and would stop developers from being able 
to rely on reflection to discern static classes for new and/or refactored code 
when that otherwise could have been possible. 

Disabling existing features just for static classes would result in creating 
two forms of static classes — explicit and implicit — and that IMO would be a 
miss for the addition of static classes.  

That said...
>   1. Since a "static class" implies all members are static, should we still 
> allow explicit static method declarations with the `static` keyword?
> 

Yes, but optional. 

Supporting the static `keyword` for members would ease the transition for 
tooling, and support those who prefer to be explicit in all the things.

OTOH, of all the things I mention below, this is my least firmly-held opinion.
>   2. Should `static` imply `final`?
> 

No. 

The primary PHP framework I wrote before I quite working professionally in PHP 
— although others still use it — has a series of implied static classes, all of 
which inherit from a base implied static class that provided services to all 
other implied static classes.  To update this library to a newer version of PHP 
with static classes would not be possible if static classes are assumed to be 
`final`.

Further, Laravel — which I have never used but is simultaneously the most 
beloved framework in PHP but also the most hated, depending on who you ask — 
has a base `Model` class that Eloquent models inherit from, and a 
`BaseController` for custom controllers.  Enforcing `final` would leave Laravel 
out in the lurch for classes that are exactly the type of classes that should 
be declared static.

If a developer wants their declared static class to be final they should be 
required to use the `final` keyword, IMO.

BTW, see #4 and #5 why this is important.
>   3. Should a "static class" prohibit inheritance?
> 

Isn't #3 just a rewording of #2?  
>   4. Should a "static class" permit state?
> 

Absolutely, without a doubt.

My PHP library uses static properties to keep track of certain data which I 
treated as immutable — registering business information for use by static 
factory methods, and in some cases the factory methods use arrays to store 
instances they create for processing and/or dispensing on demand late by other 
static methods.

Laravel uses static properties in their service containers such as 
`Illuminate\Support\Facades\App`, their Cache facade uses static properties, 
Eloquent models maintain state in static properties, and developer written 
factory classes often use static properties to track instances.

While we can ignore my library it would be much harder to ignore Laravel's use 
of state in static properties.
>   5. Should traits be permitted in a static class?
> 

Of course.  

Laravel makes extensive use of traits in their implied static classes, in their 
core framework and in Eloquent models, and they encourage Laravel application 
developers to use traits in their applications.

Traits are a valuable code structuring mechanism as an alternate to inheritance 
more like containment, and not supporting traits would, again, be leaving 
developers depending on it out in the cold.

Also, final/inheritance might not be as critical to support if it were not for 
one capability that PHP's traits are glaringly missing and that is their 
inability to allow developers to declare properties and methods as private to 
the trait itself.

Of course if we add trait-private to traits then it would be less problematic 
to implied `final`/not support inheritance, but I doubt we'd want to couple 
this potential RFC with one that hasn't even been considered yet. 

Even so, not supporting inheritance would mean not allowing implied static 
classes that use inheritance to be refactored to use the static declaration.
>   6. Which magic methods (if any) should be valid in a static class?
> 

Unless I am mistaken, the only magic method that support static function calls 
is `__callStatic()` as everything else deals with instances, so I assume that 
it is the only one that needs to be supported.

And yes, IMO it is critical to support `__callStatic()` since Laravel Facades 
(as well as my own library) make use of it, and in Laravel's case, extensive 
use.  

Of course there may(?) be newer PHP features on the horizon that are an 
alternate to `__callStatic()` but supporting `__callStatic()` would make it 
easier for developers to move to static classes as even automated tooling could 
make the conversion if `__callStatic()` and all other features used in the wild 
are supported. 

Anyway, that is my take. #fwiw

-Mike

P.S. To learn about Laravel's uses of implied static classes I asked 
ChatGPT[1], so if I got anything wrong about Laravel I apologize as I was 
relying on ChatGPT not to hallucinate on this topic. I assumed it was unlikely 
to hallucinate given there was so much info on the web there is regarding 
Laravel for ChatGPT to train on.

[1] https://chatgpt.com/share/79eb330b-69ae-4104-b2ac-6e77955ec914

Reply via email to