Re: [PHP-DEV] [RFC] Static class

2024-07-12 Thread Mike Schinkel
> On Jul 11, 2024, at 8:14 PM, Bilge  wrote:
> 
> On 25/06/2024 16:17, Derick Rethans wrote:
>> we shouldn't be encouraging static classes as 
>> a bag of static functions, that ought to be just namespaced functions.
>> 
>> cheers,
>> Derick
>> 
> Can someone clue me in as to why grouping related functions in a file with 
> nothing but a namespace is strictly better than those same related functions 
> grouped as members of a class? It doesn't have to be Larry or Derick, because 
> even though they have expressed this view, I am aware they are not the only 
> ones whom hold it. Anyone who can shed some light on this perspective is 
> welcome to comment.

I cannot answer your question as posed but I can give you a counter-reason, one 
supporting the use of static classes as a bag of static functions, at least 
with the feature set of PHP 8.4 and prior.  

If a developer needs to hide global state — and there are valid reasons for 
maintaining global state using static classes along with a related set of 
static functions. Minimally, when using streams with include*()/require*() e.g. 
include("myprotocol://${handle}") namespaces simply do not have the necessary 
visibility scoping features and thus are not an option.

I am currently working on a PoC for packages in userland that uses static 
classes exactly in this way. I will hopefully be able to share working code for 
that soon.

-Mike

P.S. None of include*()/require*() accept a stream context AFAICT. If they did 
a developer could pass in a dependency object as a context, but currently 
(again, AFAICT) there is no way to associate a dependency object with an 
include*()/require*() call. The only approach I have been able to identify to 
allow access to retrieve and update a dependency object is to use a key into a 
array in a private static property with public static get/set methods.  

If context were added to include*()/require*() and/or visibility scoping where 
added to symbols within namespaces then this use-case would no longer be an 
argument for static classes. But unless and until then, static classes are the 
only way to go. #fwiw

Re: [PHP-DEV] [RFC] Static class

2024-07-11 Thread Lanre
On Thu, Jul 11, 2024 at 6:16 PM Bilge  wrote:

> On 25/06/2024 16:17, Derick Rethans wrote:
>
> we shouldn't be encouraging static classes as a bag of static functions, that 
> ought to be just namespaced functions.
>
> cheers,
> Derick
>
> Can someone clue me in as to why grouping related functions in a file with
> nothing but a namespace is strictly better than those same related
> functions grouped as members of a class? It doesn't have to be Larry or
> Derick, because even though they have expressed this view, I am aware they
> are not the only ones whom hold it. Anyone who can shed some light on this
> perspective is welcome to comment.
>
> Cheers,
> Bilge
>

It isn't implicitly better, but if PHP had proper support for autoloading
functions, I would at least consider them equivalent when all the
functions/methods are public.

My primary language is C++, where the distinction is even blurrier since
both static class members and namespace members are accessed with '::'. For
example, X::Y() could be a namespaced function or a static method, and it
doesn't actually matter which it is under the hood since they are
functionally identical.

In PHP, however, putting all your functions in a namespace is less
performant than using static classes. For instance, if you have ten
functions.php files each for a separate namespace, Composer will load all
ten for every single request, regardless of whether they are used.
Additionally, if you install a Composer package that registers some
functions, those will also be loaded for every request.

Cheers,

Lanre


Re: [PHP-DEV] [RFC] Static class

2024-07-11 Thread Bilge

On 25/06/2024 16:17, Derick Rethans wrote:

we shouldn't be encouraging static classes as a bag of static functions, that 
ought to be just namespaced functions.

cheers,
Derick


Can someone clue me in as to why grouping related functions in a file 
with nothing but a namespace is strictly better than those same related 
functions grouped as members of a class? It doesn't have to be Larry or 
Derick, because even though they have expressed this view, I am aware 
they are not the only ones whom hold it. Anyone who can shed some light 
on this perspective is welcome to comment.


Cheers,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-07-08 Thread Bilge

On 08/07/2024 15:13, Alexandru Pătrănescu wrote:
But I understand that once a class is static, all the chain of 
inheritance should be made of static classes, going up or down (and I 
would also think we can add interfaces and traits.).

Correct.

If interfaces are not included, do we allow implementing an interface?

Yes.
If we allow implementing an interface, should that interface contain 
only static members?
Yes. You can technically implement an interface that has instance 
methods, but you will either: get a compile-time error that you didn't 
implement the instance method, or a compile-time error that you didn't 
mark the (instance) method as static in a static class. So although you 
won't get an error about implementing the interface itself, you will be 
forced to not implement an interface containing any instance methods in 
a static class, by one of those two (somewhat indirect) errors.

Same for traits.

Yes
For completeness, if we think that the static keyword on a class-level 
entity means that it will allow only static members on that entity, 
all class-level entities should be able to be marked as "static".:


I understand that sentiment, however I'm still not going to entertain it 
right now because this RFC seems to have a tenuous chance of passing at 
best. I should think we will be lucky to get 50% of the vote, let alone 
the 66% required to pass, and any further (unnecessary) language 
changes, such as introducing `static interface` or `static trait`s will 
probably lower those odds. I'm sorry it's like that, but that's how the 
landscape looks to me. But not to be too disheartened; both of those 
things can be trivially added in a follow-up PR if there is a strong 
desire. That is, accepting this RFC in no way precludes the possibility 
of going down that road later.


Cheers,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-07-08 Thread Alexandru Pătrănescu
On Mon, Jul 8, 2024 at 3:22 PM Bilge  wrote:

> On 08/07/2024 12:48, Alexandru Pătrănescu wrote:
>
>
> If we support inheritance for static classes, we should allow static on
> both interface and abstract classes.
>
> What do you mean by *allow static on [...] interface*? Are you saying you
> also expect to see `static interface` support? (This is something I am
> absolutely not considering at this time, without a very good argument in
> favour of).
>
>
> For completeness, if we think that the static keyword on a class-level
entity means that it will allow only static members on that entity, all
class-level entities should be able to be marked as "static".:
Yes, it might not be really required, but I can see how it would help
define a static interface that can only be implemented by a static class.

Reading on :
> A static class only permits extending a parent class that is also marked
static. A non-static class cannot extend a static class.

The wording is a bit confusing for me.
But I understand that once a class is static, all the chain of inheritance
should be made of static classes, going up or down (and I would also think
we can add interfaces and traits.).
If interfaces are not included, do we allow implementing an interface? If
we allow implementing an interface, should that interface contain only
static members? Same for traits.

Alex


Re: [PHP-DEV] [RFC] Static class

2024-07-08 Thread Bilge

On 08/07/2024 12:48, Alexandru Pătrănescu wrote:


On Mon, Jul 8, 2024 at 1:12 PM Stephen Reay  
wrote:




So really the question should be: why do you feel the need to
*disallow* a combination that has no technical issues, and works
already? If you're going to disallow abstract why not disallow any
class inheritance at all? Because that's what abstract relates to:
class hierarchy. Why remove some support but keep the rest?

The reason to remove abstract was because it was thought `static` means 
the same as `abstract`. That is, neither can be instantiated. However, 
clearly that is short-sighted as Alex's example proves. That is, we 
cannot simply replace `abstract` with `static` because that precludes us 
from having an incomplete definition where some methods are still not 
yet implemented. As such, I am quite convinced by your arguments, and 
will make the change to add `abstract` support back in; mainly because 
removing abstract support defies our fundamental razor (it's something 
we can already do).


If we support inheritance for static classes, we should allow static 
on both interface and abstract classes.


What do you mean by /allow static on [...] interface/? Are you saying 
you also expect to see `static interface` support? (This is something I 
am absolutely not considering at this time, without a very good argument 
in favour of).


Cheers,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-07-08 Thread Alexandru Pătrănescu
On Mon, Jul 8, 2024 at 1:12 PM Stephen Reay 
wrote:

>
>
> So really the question should be: why do you feel the need to *disallow* a
> combination that has no technical issues, and works already? If you're
> going to disallow abstract why not disallow any class inheritance at all?
> Because that's what abstract relates to: class hierarchy. Why remove some
> support but keep the rest?
>
>
>
Exactly what I wanted to say for this topic. Have a look at this example
that could be very similar in production code in some systems:



Re: [PHP-DEV] [RFC] Static class

2024-07-08 Thread Stephen Reay


> On 8 Jul 2024, at 14:42, Bilge  wrote:
> 
> On 08/07/2024 01:16, Mike Schinkel wrote:
>> Congrats on getting it to this point.
> Thanks. It's been an adventure :^)
> 
>> I support this in all but the RFC's restriction on `abstract`, as I have 
>> previously mentioned on the list.
> I must have missed a key point here. Let's suppose we're writing a follow-up 
> RFC to permit `static` and `abstract` together. In as few sentences as 
> possible, what is the benefit conferred to the developer?
> 
> Cheers,
> Bilge
> 


Hi,

I'm sure Mike has his own answer for this, but I'm going to reiterate mine 
again, because it apparently wasn't really understood the first several times I 
said it:

The reasons are two fold:

(a) so that a static class can declare abstract methods either explicitly or 
implicitly (by implementing an interface without providing concrete 
implementations of all methods in the interface)

(b) to keep consistency with regular classes. 


The suggested static keyword for classes doesn't introduce any additional 
behaviour that isn't already possible, it just prevents some uses without the 
need for boilerplate - the main purpose is to "signify developer intent".

The actual behaviour applied to "static" classes is already possible in PHP by 
simply omitting any instance members and declaring a private constructor. These 
classes work fine with the abstract keyword. There are no ambiguities, no 
gotchas or foot guns, there is nothing confusing. It's a standard part of class 
hierarchy.


So really the question should be: why do you feel the need to *disallow* a 
combination that has no technical issues, and works already? If you're going to 
disallow abstract why not disallow any class inheritance at all? Because that's 
what abstract relates to: class hierarchy. Why remove some support but keep the 
rest?




Cheers

Stephen 





Re: [PHP-DEV] [RFC] Static class

2024-07-08 Thread Bilge

On 08/07/2024 01:16, Mike Schinkel wrote:


Congrats on getting it to this point.


Thanks. It's been an adventure :^)


I support this in all but the RFC's restriction on `abstract`, as
I have previously mentioned on the list.

I must have missed a key point here. Let's suppose we're writing a 
follow-up RFC to permit `static` and `abstract` together. In as few 
sentences as possible, what is the benefit conferred to the developer?


Cheers,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-07-07 Thread Mike Schinkel
> On Jul 7, 2024, at 4:08 PM, Bilge  wrote:
> 
> On 24/06/2024 00:10, Bilge wrote:
>> Hi Internals!
> I am excited to announce the final implementation for Static Class is ready 
> for review at  and includes a 
> brief summary of the key semantics of the feature.
> 
> Furthermore, the 1.3 (presumed) final version of the RFC is now published at 
> .

Congrats on getting it to this point.

I support this in all but the RFC's restriction on `abstract`, as I have 
previously mentioned on the list.

-Mike

> Naturally, if there are any further weighty comments or criticisms to be 
> levied against either one of these, they may still be subject to changes as 
> appropriate.
> 
> Tomorrow the minimum period elapses before the vote may be started. 
> Discussions on this topic have been quiet for about a week as well, so if 
> there are no major concerns outstanding, I expect to announce the vote to 
> start very soon.
> 
> Kind regards,
> Bilge



Re: [PHP-DEV] [RFC] Static class

2024-07-07 Thread Bilge

On 30/06/2024 16:10, Tim Düsterhus wrote:
I strongly favor an opinionated RFC where the RFC author did their 
research and makes it clear why the proposal is the right choice and 
backs this up by proper arguments. Of course this doesn't mean that 
the RFC author should not listen to the list discussion, but the high 
level details should be clear right from the beginning. As of now the 
RFC still has some open questions regarding "core functionality" and 
even intents to leave them as a secondary vote.


In other words, too many cooks spoil the broth. 
I won't pretend I had the knowledge and experience to tackle this alone. 
I stood on the shoulders of giants to make this PR possible, and even 
before PR, I didn't have a clear view when I first casually strolled 
into internals. Talking to the experts here helped me find the words I 
was searching for and ensure edge cases were considered. That said, I 
hope you don't think me soft, this was not a design by committee; the 
RFC is a product of my own work and the decisions now made are a result 
of my own convictions, bolstered but not coerced by the input of others. 
Moreover, now the RFC is finished at version 1.3, I am very proud of 
what it has become and stand by every implementation decision made 
pertaining to specific semantics; I am convinced they are correct and 
would not benefit from any further modification, with the benefit of 
experience writing the implementation behind me. I hope you, too, are 
equally convinced if you would now humble me with another read.


Kind regards,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-06-30 Thread Mike Schinkel
> On Jun 30, 2024, at 11:10 AM, Tim Düsterhus  wrote:
> I strongly favor an opinionated RFC where the RFC author did their research 
> and makes it clear why the proposal is the right choice and backs this up by 
> proper arguments. Of course this doesn't mean that the RFC author should not 
> listen to the list discussion, but the high level details should be clear 
> right from the beginning. As of now the RFC still has some open questions 
> regarding "core functionality" and even intents to leave them as a secondary 
> vote.

With respect, I completely support your right to choose what you favor. 

However, I would like to suggest there might be some negative consequences to 
your approach and request that you reconsider your what you favor.

Yes, if an RFC author does their research and makes it clear why the proposal 
is the right choice and backs this up by proper arguments then it makes for a 
better RFC which can more easily be reviewed.

OTOH, it limits the pool of RFC authors who can successfully achieve that bar 
to only those who know what research needs to be done and which arguments 
resonate well resonate with list members. Effectively it limits the successful 
pool of RFC authors to the list of prior successful RFC authors who — through 
experience — have developed enough knowledge about what research needs to be 
done and which arguments resonate well with list members. 

Yes someone can overcome these experience barriers by submitting numerous RFCs 
that fail and over years of time eventually gain enough knowledge and 
experience to succeed, but realistically how many people will go through that 
gauntlet?

The problem with the approach is there over time there becomes is a diminishing 
number of individuals who can and will submit RFCs, and the language slowly 
dies:

https://thenewstack.io/why-php-usage-has-declined-by-40-in-just-over-2-years/

Currently the culture of this list is people submit an RFC and if they can 
endure the crucible to come out the other side their RFC may be adopted. But 
few can endure that crucible. Further, brainstorming on the list — as recent 
evidence has shown — is effectively impossible.

The experienced RFC submitters know to go off list and work with other 
experienced RFC submitters to prepare an RFC prior to having to endure an 
onslaught of criticism from this list. The problem for new RFC writers is they 
don't know who to ask nor have the clout to approach people to get such 
collaborators.

IMO it would be better if the culture here approached would-be RFC writers 
differently.  I instead experienced RFC writers provided a bit of mentoring to 
new RFC writers, encourage them to cultivate their ideas in a 
version-controlled repo off this list, but also have the mentor call for list 
members to collaborate with the would-be RFC writer in a discussion forum on 
their repo. Once those collaborators feel the RFC is fully-baked then they 
could present to the list. 

If that culture existed, your strongly favored well-researched and 
clearly-argued RFC could be the norm rather than the exception.

Food for thought?

-Mike
P.S. I currently have a repo for an RFC where I want to make a call for 
collaboration, but I do not know how to call for help on the list without 
attracting those who would immediately swarm the discussion forum to flood the 
channel with criticism before the ideas are even fully baked.


Re: [PHP-DEV] [RFC] Static class

2024-06-30 Thread Tim Düsterhus

Hi

On 6/28/24 21:29, Bilge wrote:

I'm already leaning towards "Don't want static classes"


Why? It is important to understand what your misgiving are in case there
anything we can do to assuage them.


I don't see value in being able to explicitly mark a class as `static` 
for the reasons that have already been brought forward by other 
participants (such as Larry).


But more importantly, the RFC and discussion so far don't really 
convince me that any of the participants in favor of static classes 
really know what they want and thought about *all* the implications of that.


I strongly favor an opinionated RFC where the RFC author did their 
research and makes it clear why the proposal is the right choice and 
backs this up by proper arguments. Of course this doesn't mean that the 
RFC author should not listen to the list discussion, but the high level 
details should be clear right from the beginning. As of now the RFC 
still has some open questions regarding "core functionality" and even 
intents to leave them as a secondary vote.


In other words, too many cooks spoil the broth.

Given the upcoming feature freeze, the current list volume and core 
folks being busy with finishing up and polishing their own RFCs for PHP 
8.4, the timing doesn't really help getting the necessary attention 
towards your RFC either. I might be more receptive towards a quieter 
period of the year, where I can take the time to really think about the 
RFC, like I do for other RFCs as well. My earlier responses towards the 
Lazy Objects RFC might be a good example towards the level of detail I 
try to give RFCs. Even when I don't personally understand them or don't 
see myself using them (yet), I want a best-possible result that will not 
cause sadness 3 years down the road.


Best regards
Tim Düsterhus


Re: [PHP-DEV] [RFC] Static class

2024-06-30 Thread Tim Düsterhus

Hi

On 6/29/24 17:56, Bilge wrote:

   - Why is it a class-level flag and not an attribute (similar to the 
`#[Override]` attribute in PHP 8.3) ?

I believe Tim already answered this, and I understood his reasoning to
be that keywords are used when they modify behaviour in a way that is
meaningful for the consumer of that class. Or to put it another way,
attributes are purely informational. For me personally, introducing an


You understood that correctly.

The forward compatibility argument brought forward by the other 
participants is not really useful either, because consider the following:


#[StaticClass]
class Foo {
public static function myFunc() { }
}

class Bar extends Foo {
public function myNonStaticFunc() { }
}

This would work fine in PHP 8.3, but break when upgrading to PHP 8.4! By 
using a keyword it is guaranteed that the code only runs on PHP versions 
that will reliably enforce all the constraints, preventing this gotcha 
during a PHP version upgrade.


Best regards
Tim Düsterhus


Re: [PHP-DEV] [RFC] Static class

2024-06-29 Thread Bilge

Hi Ayesh,

On 24/06/2024 08:53, Ayesh Karunaratne wrote:

  - Why is it a class-level flag and not an attribute (similar to the 
`#[Override]` attribute in PHP 8.3) ?
I believe Tim already answered this, and I understood his reasoning to 
be that keywords are used when they modify behaviour in a way that is 
meaningful for the consumer of that class. Or to put it another way, 
attributes are purely informational. For me personally, introducing an 
attribute never crossed my mind, and since we already have the keyword 
in the language performing a similar function in PHP, and other 
languages already, it seems nonsense to contemplate anything else.

  - Can a subclass extend a static parent class without using the
`static` keyword in the subclass? This will avoid a lot of BC issues
if a library decides to declare classes as static.
No, a static parent implies a static child, but implied or not, it must 
still be specified explicitly. I may need to clarify that in the RFC, so 
thanks for the question.

  - Are there any opt-out mechanisms for subclasses?
Not sure what you mean exactly, but if you mean, can a static subclass 
suddenly become non-static, the answer is no.Again thanks for the 
question, as this is also something I had no previously considered.

  - Can you mark interfaces, abstract classes, and Enums as static?


It seems others avoided addressing this question, and honestly I was not 
really sure where to go with this one. What would it mean for an enum to 
be static? I thought the whole point was we can type a group of values, 
but static classes have no meaning within the type system, so I cannot 
see the application.


As for abstract classes, the current version of the RFC (1.2) now 
declares static mutually exclusive with abstract, so the answer there is 
also no.


For interfaces, I haven't given this a great deal of thought. In 
principle I don't think a static interface is especially useful, but I 
could be wrong about this. Nevertheless, it is not something I intend 
for this RFC, since even just static classes already have their 
detractors, and expanding its scope any further is probably placing it 
further in danger of rejection. So for now, the answer is also no, but 
static interfaces seem like a reasonable extension to this work if there 
is interest in future.


Cheers,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-06-28 Thread Benjamin Außenhofer
On Mon, Jun 24, 2024 at 1:15 AM Bilge  wrote:

> Hi Internals!
>
> I am pleased to present my first 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!
>

while i wouldn't ordinarily find a lot of use-cases for myself for this, i
think its consistent with final and readonly to allow static on classes as
well. The code I believe would be mostly at compile time anyways to do
these checks, except for new $class.

So in general I would vote yes for this, if all edge cases are clear and
considered.

>
> Cheers,
> Bilge
>


Re: [PHP-DEV] [RFC] Static class

2024-06-28 Thread Bilge

Hi Tim,
On 27/06/2024 19:24, Tim Düsterhus wrote:

On 6/25/24 05:17, Stephen Reay wrote:
and I'd rather have the feature with slightly odd syntax rather than 
not at all.


Absolutely not. PHP is already odd enough as it is. We should not add 
additional oddness in the interest of pushing a new screw-shaped 
feature in with a sledgehammer. Any additional oddity makes it harder 
for Junior developers and developers coming from a different language 
to learn PHP and also required the developer to learn the language 
details by heart instead of being able to rely on their intuition.
Don't worry, I couldn't bring myself to seriously entertain using an 
attribute instead of a keyword. I'll update the RFC to include it as a 
rejected feature.

I'm already leaning towards "Don't want static classes"


Why? It is important to understand what your misgiving are in case there 
anything we can do to assuage them.


Cheers,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-06-28 Thread Lynn
On Fri, Jun 28, 2024 at 8:04 PM Stephen Reay 
wrote:

>
>
> On 28 Jun 2024, at 14:05, Lynn  wrote:
>
>
>
> On Fri, Jun 28, 2024 at 2:48 AM Mike Schinkel  wrote:
>
>> >> and inheritance is not meant for code reuse.
>>
>> Just because code reuse in inheritance can be problematic it does not
>> have to be in all-cases. Moderation in all things. I used that approach for
>> 10+ years and never once had any of the problems people claim about using
>> inheritance for code reuse. This was likely because my needs were
>> constrained by the use-case and by nature did not grow out of control with
>> complexity.
>>
>
> My experience is the opposite. There are subtle bugs I keep running into
> with static function and properties causing unexpected behavior. I'm not
> against having static classes open by default for the sake of consistency,
> though my preference would be to avoid the headache altogether and just
> make them final by default so I won't ever have to deal with it. Would
> traits not solve the problem of horizontal reuse?
>
>
> Hi Lynn,
>
> I understand it's frustrating when there are bugs/unexpected behaviour,
> but wouldn't the (existing) *ability* to add the `final` keyword to a class
> solve those issues for you, without preventing others from using the
> capabilities of parent/child class relationships?
>
>
> Cheers
>
>
> Stephen
>

The main issue is that it's easy to mess up by default and not messing up
requires you to understand why. I prefer defensive programming, close it
and only open when it's really required. If there's legit scenarios where
you need inheritance in a static context the requirement could be an "open"
keyword or removing it being final, we can't do it the other way around
without massive BC break.


Re: [PHP-DEV] [RFC] Static class

2024-06-28 Thread Stephen Reay


> On 28 Jun 2024, at 14:05, Lynn  wrote:
> 
> 
> 
> On Fri, Jun 28, 2024 at 2:48 AM Mike Schinkel  > wrote:
>> >> and inheritance is not meant for code reuse.
>> 
>> Just because code reuse in inheritance can be problematic it does not have 
>> to be in all-cases. Moderation in all things. I used that approach for 10+ 
>> years and never once had any of the problems people claim about using 
>> inheritance for code reuse. This was likely because my needs were 
>> constrained by the use-case and by nature did not grow out of control with 
>> complexity.
> 
> My experience is the opposite. There are subtle bugs I keep running into with 
> static function and properties causing unexpected behavior. I'm not against 
> having static classes open by default for the sake of consistency, though my 
> preference would be to avoid the headache altogether and just make them final 
> by default so I won't ever have to deal with it. Would traits not solve the 
> problem of horizontal reuse?

Hi Lynn,

I understand it's frustrating when there are bugs/unexpected behaviour, but 
wouldn't the (existing) *ability* to add the `final` keyword to a class solve 
those issues for you, without preventing others from using the capabilities of 
parent/child class relationships?


Cheers


Stephen 

Re: [PHP-DEV] [RFC] Static class

2024-06-28 Thread Lanre
On Fri, Jun 28, 2024 at 1:05 AM Lynn  wrote:

>
>
> On Fri, Jun 28, 2024 at 2:48 AM Mike Schinkel  wrote:
>
>> >> and inheritance is not meant for code reuse.
>>
>> Just because code reuse in inheritance can be problematic it does not
>> have to be in all-cases. Moderation in all things. I used that approach for
>> 10+ years and never once had any of the problems people claim about using
>> inheritance for code reuse. This was likely because my needs were
>> constrained by the use-case and by nature did not grow out of control with
>> complexity.
>>
>
> My experience is the opposite. There are subtle bugs I keep running into
> with static function and properties causing unexpected behavior. I'm not
> against having static classes open by default for the sake of consistency,
> though my preference would be to avoid the headache altogether and just
> make them final by default so I won't ever have to deal with it. Would
> traits not solve the problem of horizontal reuse?
>


Sounds like a 'you' problem. Can you go into more details about said subtle
bugs? With examples if possible?

Lanre


Re: [PHP-DEV] [RFC] Static class

2024-06-28 Thread Lynn
On Fri, Jun 28, 2024 at 2:48 AM Mike Schinkel  wrote:

> >> and inheritance is not meant for code reuse.
>
> Just because code reuse in inheritance can be problematic it does not have
> to be in all-cases. Moderation in all things. I used that approach for 10+
> years and never once had any of the problems people claim about using
> inheritance for code reuse. This was likely because my needs were
> constrained by the use-case and by nature did not grow out of control with
> complexity.
>

My experience is the opposite. There are subtle bugs I keep running into
with static function and properties causing unexpected behavior. I'm not
against having static classes open by default for the sake of consistency,
though my preference would be to avoid the headache altogether and just
make them final by default so I won't ever have to deal with it. Would
traits not solve the problem of horizontal reuse?


Re: [PHP-DEV] [RFC] Static class

2024-06-27 Thread Mike Schinkel
> On Jun 27, 2024, at 2:11 PM, Tim Düsterhus  wrote:
> Marking a class as 'static' *does* affect how the class may be used and thus 
> the static-ness is part of the public API. Therefore it should be a keyword. 
> Everything else would also be inconsistent with final classes effectively 
> making all members final and readonly classes making all members readonly.

Very insightful; that is a great rule of thumb.

>> I also believe that static classes should be implictly final. Given that no 
>> objects of such a class can exist, they cannot be exchanged by a different 
>> class anyways 

I object here. 

There are functions in classes that I have built in the past that are static 
and also benefit from inheritance.  Could they be called directly on the base 
class; yes?  But that is less elegant and increases complexity with two levels 
of inheritance are needed.  

Specifically the functionality I am thinking of is the base class is generic 
functionality for factory functions and then child factory functions implement 
use-case specific logic for the type of the object produced. For example, each 
of these functions has a MakeNew(...) function, and children call 
self::MakeNew(...).

Base
-- Term
-- User
-- BasePost
-- Post
-- Page

That is a subset of classes I used, and those classes were designed for use 
with WordPress. 

Further, these classes implemented "hooks" in WordPress. Using inheritance 
allowed all the hooks to be managed without repeating them in many places, 
being able to modify them for a class-specific need, and also without 
accidentally forgetting to add them.

>> and inheritance is not meant for code reuse.

Just because code reuse in inheritance can be problematic it does not have to 
be in all-cases. Moderation in all things. I used that approach for 10+ years 
and never once had any of the problems people claim about using inheritance for 
code reuse. This was likely because my needs were constrained by the use-case 
and by nature did not grow out of control with complexity.

So I would really hate to finally get static classes but still not be able to 
use them as intended for select use-cases only because someone decided without 
knowing all applicable use-cases that they did not like the idea of people 
using inheritance.

-Mike


Re: [PHP-DEV] [RFC] Static class

2024-06-27 Thread Lanre
On Thu, Jun 27, 2024 at 1:18 PM Tim Düsterhus  wrote:

> It should not. See: readonly classes. I also believe that static classes
> should be implictly final. Given that no objects of such a class can
> exist, they cannot be exchanged by a different class anyways and
> inheritance is not meant for code reuse.
>
>
I don't agree that they should be implicitly final, or that inheritance is
not meant for code reuse. It is currently possible eg:
https://gist.github.com/oplanre/6894f56fb61134ee5ea93cf262ba3662 and I
don't see why that should change, unless you have any solid reasons as to
why.

Lanre


Re: [PHP-DEV] [RFC] Static class

2024-06-27 Thread Tim Düsterhus

Hi

On 6/25/24 10:41, Stephen Reay wrote:

Like I said, I much prefer the keyword syntax - but I also recognise that 
others may have different priorities in terms of supporting older language 
versions, which is why I think that aspect is worth consideration (perhaps a 
secondary vote, or an informal vote to gauge consensus?), because too many good 
RFCs get rejected over small details.


Syntax is absolutely not a small detail. It's the most user-visible part 
of a language feature that is not just a new part in the standard 
library. And that is probably the reason why it's the most hotly debated 
part of any new language feature that is proposed.


As said in my previous email, I strongly oppose inventing new syntax and 
instead borrow syntax from existing (related) features as much as 
possible. An example that comes to my mind would be the initial 
brace-based syntax for the clone-with RFC that has since been replaced 
by array-style syntax that should be immediately understandable by any 
PHP programmer. PHP should continue to look and feel like PHP.


Best regards
Tim Düsterhus


Re: [PHP-DEV] [RFC] Static class

2024-06-27 Thread Tim Düsterhus

Hi

On 6/25/24 05:17, Stephen Reay wrote:

and I'd rather have the feature with slightly odd syntax rather than not at all.


Absolutely not. PHP is already odd enough as it is. We should not add 
additional oddness in the interest of pushing a new screw-shaped feature 
in with a sledgehammer. Any additional oddity makes it harder for Junior 
developers and developers coming from a different language to learn PHP 
and also required the developer to learn the language details by heart 
instead of being able to rely on their intuition.


I'm already leaning towards "Don't want static classes", but if they use 
an attribute instead of a keyword, then it's going to be a clear "no". 
See also my email in response to Ayesh.


Best regards
Tim Düsterhus

PS: Can you please cut the quoted parts to a minimum instead of 
including the original email in full? That makes it much clearer to see 
what part you are actually replying to and reduces the amount of storage 
requiring for all the thousands of ML subscribers :-)


Re: [PHP-DEV] [RFC] Static class

2024-06-27 Thread Tim Düsterhus

Hi

On 6/24/24 09:53, Ayesh Karunaratne wrote:

Personally, I think this will be a useful feature. Just like we have
`readonly` properties and `readonly` classes, I don't see why we can't
have static methods. I also saw in the draft PR that it does not
require a lot of changes to the engine to have this.

I'd like to propose to add some more information and points addressed
in the RFC. This is of course merely a suggestion, but it's something
I was thinking when reading the RFC.

  - Why is it a class-level flag and not an attribute (similar to the
`#[Override]` attribute in PHP 8.3) ?


To quote myself from the #[\Override] RFC:


This RFC proposes an attribute instead of a keyword, because contrary to other 
modifiers (e.g. visibility) that are part of the method signature, the 
attribute does not affect behavior or compatibility for users that further 
extend a given class and neither does it affect users that call the method. It 
is purely an assistance to the author of a given class.



Marking a class as 'static' *does* affect how the class may be used and 
thus the static-ness is part of the public API. Therefore it should be a 
keyword. Everything else would also be inconsistent with final classes 
effectively making all members final and readonly classes making all 
members readonly.



  - Can a subclass extend a static parent class without using the
`static` keyword in the subclass? This will avoid a lot of BC issues
if a library decides to declare classes as static.


It should not. See: readonly classes. I also believe that static classes 
should be implictly final. Given that no objects of such a class can 
exist, they cannot be exchanged by a different class anyways and 
inheritance is not meant for code reuse.


Best regards
Tim Düsterhus


Re: [PHP-DEV] [RFC] Static class

2024-06-27 Thread Mike Schinkel
 
 

 
 

 
>  
> On Jun 27, 2024 at 3:26 AM,  mailto:php-li...@koalephant.com)> 
>  wrote:
>  
>  
>  
> I think I understand your view: you're not as concerned with consistency if 
> the alternative is something "better".   
>  
>  
>  
 
 
 
 That yes, but more importantly, that deciding NOT to disallow calling `static` 
methods on `abstract static` classes is a decision for the ages that cannot be 
reversed later because of BC.
 
 
 
 And with that, I think we've both beaten this horse to death so I am over and 
out on this topic.
 
 
 
 -Mike
 
 

Re: [PHP-DEV] [RFC] Static class

2024-06-27 Thread Stephen Reay


> On 27 Jun 2024, at 13:11, Mike Schinkel  wrote:
> 
> 
>> On Jun 27, 2024, at 12:09 AM, Stephen Reay > > wrote:
>> 
>> Hi Mike,
>> 
>> To answer your question: I believe `abstract static` should be allowed, 
>> because the "objection" mis-characterises a particular aspect of them as an 
>> unintended consequence, when there's evidence to show that's not that case.
>> 
>> Claude essentially dismisses the use of abstract static methods:
>> 
 only consequences of their intended meaning on non-static class
>> 
>> In v5.2 a strict standards notice was added regarding the use of abstract 
>> static methods in classes. No notice was ever shown when they're used in 
>> interfaces.  In v7 this notice was removed (via 
>> https://wiki.php.net/rfc/reclassify_e_strict#abstract_static_methods) 
>> because, as Nikita noted at the time:
> 
> Thank you for elaborating. 
> 
> We are on the same page here as I too think `abstract static` should be 
> allowed when declaring a class
> 
>>> We currently allow the use of abstract static functions in interfaces, as 
>>> such it is inconsistent to not allow them as abstract methods. By using 
>>> late static binding a method in the abstract class can reasonably depend on 
>>> the existence of a static method in a superclass. 
>> 
>> 
>> That to me says this is an intended feature, and not an unintended 
>> consequence.
> 
> Before I address this and your other comments, please understand that I do 
> not see this as a huge issue either way, but I do want my argument to be 
> understood. If my argument on this does not win the day, I will not lament it 
> in any way.
> 
> As an aside, I had never seen interfaces used that way and found it 
> surprising. Obviously I missed when Nikita made that claim.  
> 
> As for "an intended feature, and not an unintended consequence," when I was 
> in university they drilled the idea of a sunken cost into me to the point I 
> am a true believer. IOW, make the best decision moving forward vs. doubling 
> down on bad decisions. 
> 
> Note that I am not saying Nikita's was a bad decision (or a good one) just 
> that the existence of a prior decision should not color making the best 
> decision moving forward.
> 


I understand that, but I also think there is much value in consistency. If 
static methods (and abstract static methods) are supported, they should be 
supported consistently. There have been numerous RFCs passed that bring 
consistency (and thus remove developer surprise) to the language, even on 
features that some voters dislike so much, they'd rather the feature is 
intentionally difficult to use, to discourage use by other people (remember the 
trait constants RFC?)


> I am curious, do you know of real-world userland code that is actually 
> configured as your example that would be negatively affected by disallowing 
> static methods calls?
> 

Not in that specific case, no. I've seen some that uses `abstract class` as a 
poor mans `static class` (just to prevent instantiation) but not that uses 
`abstract` to allow omitting an upstream method.

>> On Jun 26, 2024, at 4:26 AM, Stephen Reay > > wrote:
> 
>> 
> 
>> This is an example of code that works today (and all the way back to 5.0): 
>> https://3v4l.org/4EKo2
>> The class hierarchy embody the type of classes this RFC is about: only 
>> static members, no instantiation. 
> 
>> 
> 
>> The *implemented methods* can be called statically, regardless of whether 
>> the class they're implemented in is abstract or not. The *abstract methods* 
>> cannot be called directly.
> 
> Understood, but I do not see how interfaces or instantiation or abstract 
> method are relevant to the discussion. They all seem orthogonal to me.

A class cannot contain abstract methods if it is not also marked as abstract. 
That's the whole point. If you prevent a static class from also being abstract, 
you prevent that class from partially implementing an interface (or parent 
class with abstract methods).

> 
>> So these classes would be a candidate for the `static` class keyword (or 
>> Attribute) - except they can't, if calls to implemented methods on abstract 
>> classes are disallowed. Because the Base::a() method has been publicly 
>> callable, for potentially as long as   20 years next month.
> 
> While it may be true that it has been that way, disallowing `static methods` 
> from being called using `abstract static` classes would not be a BC break 
> because it was previously impossible to declare a class as `static` let alone 
> `abstract static`.

Right so I'm not actually saying this is a BC break itself - I'm saying the 
authors of the library/code then can't adopt the `static` keyword, which 
embodies their intent fully, because if they do so *their* code has a BC break 
(code that was previously callable, it not any more). 

> 
> Further, there are often new features with constraints that result in 
> developer not being "t

Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Mike Schinkel

> On Jun 27, 2024, at 12:09 AM, Stephen Reay  wrote:
> 
> Hi Mike,
> 
> To answer your question: I believe `abstract static` should be allowed, 
> because the "objection" mis-characterises a particular aspect of them as an 
> unintended consequence, when there's evidence to show that's not that case.
> 
> Claude essentially dismisses the use of abstract static methods:
> 
>>> only consequences of their intended meaning on non-static class
> 
> In v5.2 a strict standards notice was added regarding the use of abstract 
> static methods in classes. No notice was ever shown when they're used in 
> interfaces.  In v7 this notice was removed (via 
> https://wiki.php.net/rfc/reclassify_e_strict#abstract_static_methods 
> ) 
> because, as Nikita noted at the time:

Thank you for elaborating. 

We are on the same page here as I too think `abstract static` should be allowed 
when declaring a class

>> We currently allow the use of abstract static functions in interfaces, as 
>> such it is inconsistent to not allow them as abstract methods. By using late 
>> static binding a method in the abstract class can reasonably depend on the 
>> existence of a static method in a superclass. 
> 
> 
> That to me says this is an intended feature, and not an unintended 
> consequence.

Before I address this and your other comments, please understand that I do not 
see this as a huge issue either way, but I do want my argument to be 
understood. If my argument on this does not win the day, I will not lament it 
in any way.

As an aside, I had never seen interfaces used that way and found it surprising. 
Obviously I missed when Nikita made that claim.  

As for "an intended feature, and not an unintended consequence," when I was in 
university they drilled the idea of a sunken cost into me to the point I am a 
true believer. IOW, make the best decision moving forward vs. doubling down on 
bad decisions. 

Note that I am not saying Nikita's was a bad decision (or a good one) just that 
the existence of a prior decision should not color making the best decision 
moving forward.

I am curious, do you know of real-world userland code that is actually 
configured as your example that would be negatively affected by disallowing 
static methods calls?

> On Jun 26, 2024, at 4:26 AM, Stephen Reay  > wrote:

> 

> This is an example of code that works today (and all the way back to 5.0): 
> https://3v4l.org/4EKo2 The class hierarchy embody the 
> type of classes this RFC is about: only static members, no instantiation. 

> 

> The *implemented methods* can be called statically, regardless of whether the 
> class they're implemented in is abstract or not. The *abstract methods* 
> cannot be called directly.

Understood, but I do not see how interfaces or instantiation or abstract method 
are relevant to the discussion. They all seem orthogonal to me.

> So these classes would be a candidate for the `static` class keyword (or 
> Attribute) - except they can't, if calls to implemented methods on abstract 
> classes are disallowed. Because the Base::a() method has been publicly 
> callable, for potentially as long as   20 years next month.

While it may be true that it has been that way, disallowing `static methods` 
from being called using `abstract static` classes would not be a BC break 
because it was previously impossible to declare a class as `static` let alone 
`abstract static`.

Further, there are often new features with constraints that result in developer 
not being "to do what they have been able to do for 20 years" because, looking 
forward, those constraints make more sense than not having those constraints. 

Take a look at `readonly` properties. They must be typed, but I could have used 
the same argument against that saying "We've always been able to have untyped 
properties so readonly should not have to be typed."[1] I'd say requiring them 
to be typed was a win, though, regardless of past property capabilities.

I'm not claiming necessarily that disallowing calling `static` methods on a 
`abstract static` class is a best practice, but I am saying that "we've been 
able to do it with similar syntax for a long time" is not a particularly 
compelling argument if disallowing is a better approach.

As another aside, assuming everyone agrees on what a best practice is for a 
given case, I doubt anyone would object to a constraint that forced developers 
to follow that best practice vs. allowing them to write less ideal code.

> My point here is that if someone wants to prohibit calling public static 
> methods on abstract classes *with* the static keyword, that's going be 
> inconsistent with how it's worked for the last 20 years (i.e. on classes that 
> were 'static' in intent but not syntactically),

Back to sunken cost, does it make more sense to only give developers who want 
to disallow using static m

Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Stephen Reay


> On 27 Jun 2024, at 10:11, Mike Schinkel  wrote:
> 
> Hi Stephen,
> 
>> On Jun 26, 2024, at 4:26 AM, Stephen Reay > > wrote:
>> 
>> This is an example of code that works today (and all the way back to 5.0): 
>> https://3v4l.org/4EKo2
>> 
>> The class hierarchy embody the type of classes this RFC is about: only 
>> static members, no instantiation. 
>> 
>> The *implemented methods* can be called statically, regardless of whether 
>> the class they're implemented in is abstract or not. The *abstract methods* 
>> cannot be called directly.
>> 
>> So these classes would be a candidate for the `static` class keyword (or 
>> Attribute) - except they can't, if calls to implemented methods on abstract 
>> classes are disallowed. Because the Base::a() method has been publicly 
>> callable, for potentially as long as   20 years next month.
>> 
>> My point here is that if someone wants to prohibit calling public static 
>> methods on abstract classes *with* the static keyword, that's going be 
>> inconsistent with how it's worked for the last 20 years (i.e. on classes 
>> that were 'static' in intent but not syntactically), or if it applies the 
>> change everywhere it's going to be a BC break.
> 
> It seems what you are asking about is downstream from the reason I stated 
> that I made the argument in the first place, which AFAICT you did not 
> acknowledge. That leaves me unsure of your position on a precursor topic to 
> your above stated objections.
> 
> As stated, my primary (initial) reason for arguing that `abstract static` 
> should disallow calling static methods using the class name of the static 
> class marked abstract — as my earlier example of calling `Base::foo()` 
> illustrated` — was in response to the argument against allowing `abstract` 
> with `static` because — in Claude's words — it would "have no real semantic 
> meaning for static class; their effects on static members are only 
> consequences of their intended meaning on non-static class."  I have copied 
> his complete words on that topic below:
> 
>> On Jun 24, 2024, at 4:27 AM, Claude Pache > > wrote:
>> 
>> Should a static class be marked `abstract`? I think not, because those have 
>> no real semantic meaning for static class; their effects on static members 
>> are only consequences of their intended meaning on non-static class:
>> 
>> * The main purpose of the `abstract` keyword is to prevent a class to be 
>> instantiated, which (in case of static class) is more semantically described 
>> by the `static` marker. Beyond that, it just allows to declare a method 
>> that, if implemented by a subclass, should have a compatible signature. Most 
>> notably, it does not prevent the other static members of the class to be 
>> used directly.
> 
> Thus my argument supporting `abstract static` was addressing his objections 
> by suggesting that we could have an `abstract static class` declaration 
> *disallow* calling any of the `static` methods of the class using the name of 
> the class declared `abstract` given that it would in fact not cause any BC 
> breaks with untouched code. 
> 
> Before you repeat your objections to disallowing, permit me to ask you which 
> of the following upstream arguments you are making?  Is your position that we 
> should:
> 
> 1. Disallow `abstract` on `static` as Claude argued?
> 2. Allow `abstract static` in spite of  Claude's argument against it?
> 
> Also, if you answer "2. Allow `abstract static`" then please how do you 
> address Claude's objections?
> 
> Once I am clear of your position on two above I will address your objections 
> stated in your most recent response to me, which I quoted at the beginning of 
> this email.  Thank you in advance for the clarity.
> 
> -Mike

Hi Mike,


To answer your question: I believe `abstract static` should be allowed, because 
the "objection" mis-characterises a particular aspect of them as an unintended 
consequence, when there's evidence to show that's not that case.


Claude essentially dismisses the use of abstract static methods:

>> only consequences of their intended meaning on non-static class

In v5.2 a strict standards notice was added regarding the use of abstract 
static methods in classes. No notice was ever shown when they're used in 
interfaces.  In v7 this notice was removed (via 
https://wiki.php.net/rfc/reclassify_e_strict#abstract_static_methods) because, 
as Nikita noted at the time:

> We currently allow the use of abstract static functions in interfaces, as 
> such it is inconsistent to not allow them as abstract methods. By using late 
> static binding a method in the abstract class can reasonably depend on the 
> existence of a static method in a superclass. 


That to me says this is an intended feature, and not an unintended consequence.






Cheers

Stephen 





Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Mike Schinkel
Hi Larry,

> On Jun 26, 2024, at 2:21 PM, Larry Garfield  > wrote:
> PHP has no concept of packages at present, and thus no concept of 
> package-level scope.  

Not entirely true.

PHP has static classes, which are stand-ins for packages for as long as PHP 
does not inherently support the concept of packages.

Arguing "that is abusing static" without offering an alternative is just 
Puritanistic logic that ignores pragmatic real world needs.

> For marking a function as "package private", the same way you would for a 
> package-private class today: @internal docblock.  It's not ideal (the ideal 
> would require packages), but it still communicates the intent, has worked for 
> classes for 15 years at least, and signals "if you use this 
> class/function/thing and it breaks later, that's on you, don't come crying to 
> me."

Not only is `@internal docblock` not ideal, it sets up those internal 
properties to be infected with usage as explained by Hyrum's Law[1].  Thus 
providing `@internal docblock` as if it were a viable alternative to package 
private is essentially a non-serious argument.

> PHP has no concept of packages at present, and thus no concept of 
> package-level scope.  A private static method is private not to a file or 
> package, but to that class.  (The class and file usually correlate in 
> practice, but there's nothing in the language that mandates that.)  I would 
> love to have a concept of packages that we could use for scope, as most more 
> recent languages have concluded that is the correct level at which to enforce 
> visibility, NOT objects/classes.  That's an entirely separate question, 
> however.

If you really want people to stop "abusing static" then drive to address that 
entirely separate question. Otherwise let others who are more pragmatic give 
the language features that they need.

As a quick aside, I would argue that PHP should look at its biggest warts — 
which to me include but are not limited to autoloading and namespaces — and 
deprecate them to be replaced with a proper package system that leverages a 
symbol compiler instead of autoloading and that ejects the god-awful choice of 
using the escape character for package name separation. 

But I digress.

> To be blunt, 90% of uses of static methods in PHP are a sign the developer 
> doesn't actually understand OOP and is just writing procedural code with more 
> steps.  The other 10% are either named constructors or cases that can now be 
> replaced with attributes.


Speaking of best practices, there is a growing contingent of software 
developers who feel that OOP should not be the future of software[2], e.g. that 
it was "a good idea at the time" but now no longer.

My point here is that PHP should not let entrenched dogma drive language design 
but instead pragmatically evolve as other languages are also evolving. 

-Mike

[1] https://www.laws-of-software.com/laws/hyrum/ 

[2] https://news.ycombinator.com/item?id=8676872 


Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Mike Schinkel
Hi Stephen,

> On Jun 26, 2024, at 4:26 AM, Stephen Reay  wrote:
> 
> This is an example of code that works today (and all the way back to 5.0): 
> https://3v4l.org/4EKo2 
> 
> The class hierarchy embody the type of classes this RFC is about: only static 
> members, no instantiation. 
> 
> The *implemented methods* can be called statically, regardless of whether the 
> class they're implemented in is abstract or not. The *abstract methods* 
> cannot be called directly.
> 
> So these classes would be a candidate for the `static` class keyword (or 
> Attribute) - except they can't, if calls to implemented methods on abstract 
> classes are disallowed. Because the Base::a() method has been publicly 
> callable, for potentially as long as   20 years next month.
> 
> My point here is that if someone wants to prohibit calling public static 
> methods on abstract classes *with* the static keyword, that's going be 
> inconsistent with how it's worked for the last 20 years (i.e. on classes that 
> were 'static' in intent but not syntactically), or if it applies the change 
> everywhere it's going to be a BC break.

It seems what you are asking about is downstream from the reason I stated that 
I made the argument in the first place, which AFAICT you did not acknowledge. 
That leaves me unsure of your position on a precursor topic to your above 
stated objections.

As stated, my primary (initial) reason for arguing that `abstract static` 
should disallow calling static methods using the class name of the static class 
marked abstract — as my earlier example of calling `Base::foo()` illustrated` — 
was in response to the argument against allowing `abstract` with `static` 
because — in Claude's words — it would "have no real semantic meaning for 
static class; their effects on static members are only consequences of their 
intended meaning on non-static class."  I have copied his complete words on 
that topic below:

> On Jun 24, 2024, at 4:27 AM, Claude Pache  wrote:
> 
> Should a static class be marked `abstract`? I think not, because those have 
> no real semantic meaning for static class; their effects on static members 
> are only consequences of their intended meaning on non-static class:
> 
> * The main purpose of the `abstract` keyword is to prevent a class to be 
> instantiated, which (in case of static class) is more semantically described 
> by the `static` marker. Beyond that, it just allows to declare a method that, 
> if implemented by a subclass, should have a compatible signature. Most 
> notably, it does not prevent the other static members of the class to be used 
> directly.

Thus my argument supporting `abstract static` was addressing his objections by 
suggesting that we could have an `abstract static class` declaration *disallow* 
calling any of the `static` methods of the class using the name of the class 
declared `abstract` given that it would in fact not cause any BC breaks with 
untouched code. 

Before you repeat your objections to disallowing, permit me to ask you which of 
the following upstream arguments you are making?  Is your position that we 
should:

1. Disallow `abstract` on `static` as Claude argued?
2. Allow `abstract static` in spite of  Claude's argument against it?

Also, if you answer "2. Allow `abstract static`" then please how do you address 
Claude's objections?

Once I am clear of your position on two above I will address your objections 
stated in your most recent response to me, which I quoted at the beginning of 
this email.  Thank you in advance for the clarity.

-Mike

Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Chuck Adams



> On Jun 26, 2024, at 5:49 PM, Derick Rethans  wrote:
> 
> There has been some work done on function autoloading too:
> https://wiki.php.net/rfc/core-autoloading

Fantastic!  I still want modules and/or companion objects of course...  I 
wonder whether the autoloading machinery could be bent to such a purpose, or am 
I smoking the bad stuff again?

—c


Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Lanre
On Wed, Jun 26, 2024 at 5:52 PM Derick Rethans  wrote:

> On Tue, 25 Jun 2024, Chuck Adams wrote:
>
> > > On Jun 25, 2024, at 9:17 AM, Derick Rethans  wrote:
> > >
> > > Having read this thread, and the previous one from half a year ago,
> > > I will do so too. In short, we shouldn't be encouraging static
> > > classes as a bag of static functions, that ought to be just
> > > namespaced functions.
> >
> > Which brings us back to the age-old problem that functions can’t be
> > autoloaded. Me, I want first-class modules, but until we have those, I
> > have to settle for classes in the meantime. Scala/Kotlin-like
> > “companion objects” might be a good all-round substitute though.
>
> There has been some work done on function autoloading too:
> https://wiki.php.net/rfc/core-autoloading
>
> cheers,
> Derick
>
>  My bad, I thought "top post" meant the same thing in mailing lists as it
does in forums. I am now aware of my mistake and it won't happen again. Can
we address my actual points now?

Lanre


Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Derick Rethans
On Tue, 25 Jun 2024, Chuck Adams wrote:

> > On Jun 25, 2024, at 9:17 AM, Derick Rethans  wrote:
> >
> > Having read this thread, and the previous one from half a year ago, 
> > I will do so too. In short, we shouldn't be encouraging static 
> > classes as a bag of static functions, that ought to be just 
> > namespaced functions.
> 
> Which brings us back to the age-old problem that functions can’t be 
> autoloaded. Me, I want first-class modules, but until we have those, I 
> have to settle for classes in the meantime. Scala/Kotlin-like 
> “companion objects” might be a good all-round substitute though.

There has been some work done on function autoloading too:
https://wiki.php.net/rfc/core-autoloading

cheers,
Derick



Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Derick Rethans
On Wed, 26 Jun 2024, Lanre wrote:

> That isn't a top post, look again.

It was.

If people point out you're doing something against this list's
guidelines, don't reply with "it wasn't" in a snarky way.

cheers,
Derick


Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Lanre
Also I specifically said "we can declare functions that are local to the
current file by not exporting them.", Where did you get "package private"
from?

On Wed, Jun 26, 2024 at 1:46 PM Larry Garfield 
wrote:

> On Wed, Jun 26, 2024, at 6:05 PM, Lanre wrote:
> > In JavaScript/Typescript, we can declare functions that are local to
> > the current file by not exporting them. In C/C++ this is achieved by
> > simply writing the function in the implementation file as opposed to
> > the header. However, achieving a similar level of privacy in PHP
> > requires using private static methods, or else you incur the overhead
> > of creating an object for stateless functions. How do you propose
> > handling such cases using namespaced functions? Can you think of any
> > scenarios where hiding non-API functions might be necessary? I'm
> > curious why you keep returning to namespaced functions when they don't
> > fulfill the same role.
> >
> > Cheers,
> > Lanre
>
> Please don't top-post.
>
> PHP has no concept of packages at present, and thus no concept of
> package-level scope.  A private static method is private not to a file or
> package, but to that class.  (The class and file usually correlate in
> practice, but there's nothing in the language that mandates that.)  I would
> love to have a concept of packages that we could use for scope, as most
> more recent languages have concluded that is the correct level at which to
> enforce visibility, NOT objects/classes.  That's an entirely separate
> question, however.
>
> For marking a function as "package private", the same way you would for a
> package-private class today: @internal docblock.  It's not ideal (the ideal
> would require packages), but it still communicates the intent, has worked
> for classes for 15 years at least, and signals "if you use this
> class/function/thing and it breaks later, that's on you, don't come crying
> to me."
>
> (ab)using static classes to emulate a pseudo-single-class-package is...
> abusing static.
>
> To be blunt, 90% of uses of static methods in PHP are a sign the developer
> doesn't actually understand OOP and is just writing procedural code with
> more steps.  The other 10% are either named constructors or cases that can
> now be replaced with attributes.
>
> --Larry Garfield
>


Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Lanre
That isn't a top post, look again.And I am not referring to
packages,rather to the ability to define functions that aren't exposed to
the users of a library. C doesn't have packages either yet this is possible
in it. And marking it as internal is not the same thing at all. I am not
going to argue about why a developer would use static methods and whether
that is actually a sign that the developer doesn't understand OOP. But I do
want to get this straight.  Instead of actually hiding the function, your
idea is to mark it with @internal (via PHPDoc)? To you, that solves the
problem?

On Wed, Jun 26, 2024 at 1:46 PM Larry Garfield 
wrote:

> On Wed, Jun 26, 2024, at 6:05 PM, Lanre wrote:
> > In JavaScript/Typescript, we can declare functions that are local to
> > the current file by not exporting them. In C/C++ this is achieved by
> > simply writing the function in the implementation file as opposed to
> > the header. However, achieving a similar level of privacy in PHP
> > requires using private static methods, or else you incur the overhead
> > of creating an object for stateless functions. How do you propose
> > handling such cases using namespaced functions? Can you think of any
> > scenarios where hiding non-API functions might be necessary? I'm
> > curious why you keep returning to namespaced functions when they don't
> > fulfill the same role.
> >
> > Cheers,
> > Lanre
>
> Please don't top-post.
>
> PHP has no concept of packages at present, and thus no concept of
> package-level scope.  A private static method is private not to a file or
> package, but to that class.  (The class and file usually correlate in
> practice, but there's nothing in the language that mandates that.)  I would
> love to have a concept of packages that we could use for scope, as most
> more recent languages have concluded that is the correct level at which to
> enforce visibility, NOT objects/classes.  That's an entirely separate
> question, however.
>
> For marking a function as "package private", the same way you would for a
> package-private class today: @internal docblock.  It's not ideal (the ideal
> would require packages), but it still communicates the intent, has worked
> for classes for 15 years at least, and signals "if you use this
> class/function/thing and it breaks later, that's on you, don't come crying
> to me."
>
> (ab)using static classes to emulate a pseudo-single-class-package is...
> abusing static.
>
> To be blunt, 90% of uses of static methods in PHP are a sign the developer
> doesn't actually understand OOP and is just writing procedural code with
> more steps.  The other 10% are either named constructors or cases that can
> now be replaced with attributes.
>
> --Larry Garfield
>


Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Bilge

On 25/06/2024 16:17, Derick Rethans wrote:

we shouldn't be encouraging static classes as
a bag of static functions, that ought to be just namespaced functions.


I understand this is the prevailing preference of a certain few, 
including (but not limited to) yourself and Larry. Nevertheless, classes 
as a bag of static functions is a phenomenon that exists and will 
continue to exist in PHP until such a time as `static` is completely 
removed from the language, so I don't really understand the avoidance of 
adding, in the interim, what seems like just a missing part of an 
existing feature.


However, I still want to understand why a file of functions is strictly 
better than a class of functions. What are the benefits of a file over a 
class?


For me, I dislike importing individual functions. It is often the case 
that, when such logic is so grouped in a static class, where we use one 
we may use several such functions. In such a case, we only need a single 
import statement instead of one for each function. This seems like a 
clear benefit. Even in the case that I only use one, I still prefer to 
import a class over a function, because it has better support in my 
editor and doesn't stick out like a sore thumb in the list of imports 
(why should it?).


Cheers, Bilge


Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Larry Garfield
On Wed, Jun 26, 2024, at 6:05 PM, Lanre wrote:
> In JavaScript/Typescript, we can declare functions that are local to 
> the current file by not exporting them. In C/C++ this is achieved by 
> simply writing the function in the implementation file as opposed to 
> the header. However, achieving a similar level of privacy in PHP 
> requires using private static methods, or else you incur the overhead 
> of creating an object for stateless functions. How do you propose 
> handling such cases using namespaced functions? Can you think of any 
> scenarios where hiding non-API functions might be necessary? I'm 
> curious why you keep returning to namespaced functions when they don't 
> fulfill the same role.
>
> Cheers,
> Lanre

Please don't top-post.

PHP has no concept of packages at present, and thus no concept of package-level 
scope.  A private static method is private not to a file or package, but to 
that class.  (The class and file usually correlate in practice, but there's 
nothing in the language that mandates that.)  I would love to have a concept of 
packages that we could use for scope, as most more recent languages have 
concluded that is the correct level at which to enforce visibility, NOT 
objects/classes.  That's an entirely separate question, however.

For marking a function as "package private", the same way you would for a 
package-private class today: @internal docblock.  It's not ideal (the ideal 
would require packages), but it still communicates the intent, has worked for 
classes for 15 years at least, and signals "if you use this 
class/function/thing and it breaks later, that's on you, don't come crying to 
me."

(ab)using static classes to emulate a pseudo-single-class-package is... abusing 
static.  

To be blunt, 90% of uses of static methods in PHP are a sign the developer 
doesn't actually understand OOP and is just writing procedural code with more 
steps.  The other 10% are either named constructors or cases that can now be 
replaced with attributes.

--Larry Garfield


Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Lanre
In JavaScript/Typescript, we can declare functions that are local to the
current file by not exporting them. In C/C++ this is achieved by simply
writing the function in the implementation file as opposed to the header.
However, achieving a similar level of privacy in PHP requires using private
static methods, or else you incur the overhead of creating an object for
stateless functions. How do you propose handling such cases using
namespaced functions? Can you think of any scenarios where hiding non-API
functions might be necessary? I'm curious why you keep returning to
namespaced functions when they don't fulfill the same role.

Cheers,
Lanre
On Tue, Jun 25, 2024 at 9:20 AM Derick Rethans  wrote:

> On Sun, 23 Jun 2024, Larry Garfield wrote:
>
> > On Sun, Jun 23, 2024, at 6:10 PM, Bilge wrote:
> > > Hi Internals!
> > >
> > > I am pleased to present my first 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!
>
> 
> >
> > For the record, as previously stated, I will be voting No on this RFC.
>
> Having read this thread, and the previous one from half a year ago, I
> will do so too. In short, we shouldn't be encouraging static classes as
> a bag of static functions, that ought to be just namespaced functions.
>
> cheers,
> Derick
>


Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Jordi Boggiano

On 2024-06-24 01:10, Bilge wrote:
I am pleased to present my first RFC: Static class 
.
Just one point of feedback: for clarity I think it would be good if 
it mentions that creating dynamic properties i.e. $this->dynamicProp 
= 'bar' would also throw at runtime (or even compile time if doable?).
Absolutely. I'll include a note about this in the RFC. 


On second thoughts, I don't think dynamic properties can apply at all. 
The notion of `$this` is a reference to an object instance; static 
classes cannot be instantiated, so the concept of dynamic properties 
simply cannot exist, and that's really all there is to it 😅 (unless 
I'm missing something). 


Yeah sorry that is indeed not needed as it already works that way 
https://3v4l.org/TYIiV


It is not compile time though, but that's a separate concern.

Jordi Boggiano
@seldaek - https://seld.be


Re: [PHP-DEV] [RFC] Static class

2024-06-26 Thread Stephen Reay


> On 26 Jun 2024, at 12:51, Mike Schinkel  wrote:
> 
>> On Jun 24, 2024, at 11:17 PM, Stephen Reay > > wrote:
>> 
>> 
>> 
>>> On 25 Jun 2024, at 09:22, Mike Schinkel >> > wrote:
>>> 
 On Jun 24, 2024, at 3:53 AM, Ayesh Karunaratne >>> > wrote:
 - Why is it a class-level flag and not an attribute (similar to the
 `#[Override]` attribute in PHP 8.3) ?
>>> 
>>> From my perspective that would create much confusion among every PHP 
>>> developer who has not committed to memory when to use `static` as a class 
>>> keyword and when to use it as an attribute.
>>> 
>>> Given the concept already exists in keywords I would strongly argue that it 
>>> makes no sense to introduce as an attributes in core PHP.  
>>> 
>>> Attributes are great for concepts new to PHP, IMO, but not for existing 
>>> concepts already part of PHP implemented with keywords.
>>> 
 On Jun 24, 2024, at 4:27 AM, Claude Pache >>> > wrote:
 * The main purpose of the `abstract` keyword is to prevent a class to be 
 instantiated, which (in case of static class) is more semantically 
 described by the `static` marker. Beyond that, it just allows to declare a 
 method that, if implemented by a subclass, should have a compatible 
 signature. Most notably, it does not prevent the other static members of 
 the class to be used directly.
>>> 
>>> Given a primary purpose for being able to declare a class `static` is to 
>>> signal intent, disallowing `abstract static` classes seems at odds with 
>>> that goal.
>>> 
>>> Of course it is currently true that `static` methods of `abstract` classes 
>>> can be called from outside a  class and its class hierarchy, so if we allow 
>>> declaring `abstract static` classes then it would never in the future be 
>>> possible to lock down calls of `static` methods to those `abstract` classes.
>>> 
>>> So IMO it would be better to disallow calling `static` methods from outside 
>>> a declared `abstract static` class and its inheritance hierarchy as part of 
>>> this RFC. That would be backward compatible since there are currently no 
>>> classes that are declared in that manner.  Doing otherwise would force 
>>> those who want to declare a class as both `static` and `abstract` to have 
>>> to make a choice rather than being able to signal their full intent. Which 
>>> brings us back to the "implied" vs. "explicitly declared" bifurcation I 
>>> mentioned in a prior email.
>>> 
>>> BTW, I am assuming it is technically possible to disallow calling methods 
>>> for classes declared both `abstract` and `static` without considerable 
>>> difficulty in implementation and without creating a significant drain on 
>>> performance. 
>>> 
>>> -Mike 
>>> 
>>> P.S. I would argue the same for `readonly static` properties, but as that 
>>> seems those would require an involved discussion about the exact rules to 
>>> implement I am demurring on that topic.
>> 
>> Hi Mike,
>> 
>> 
>>> So IMO it would be better to disallow calling `static` methods from outside 
>>> a declared `abstract static` class
>> 
>> Can you explain what you mean by this, or more specifically the "why". What 
>> (implied wrong/bad) scenario are you trying to prevent, by disallowing a 
>> static method on an abstract class to be called?
>> 
>> As you point out, it's already possible to call (public) static methods on 
>> abstract classes, the same as it's possible to call (public) static methods 
>> without instantiating a regular class.
>> 
>>  So why should static abstract classes be different? If the static method 
>> shouldn't be called publicly, it shouldn't be public. Are you suggesting 
>> that public static methods shouldn't be callable on *any* abstract class? If 
>> so, this sounds like a huge BC break, and if not, it sounds like a confusing 
>> "if-then-but-why" scenario.
> 
> Thank you for the question.
> 
> I was not specifically advocating `static` methods to be disallowed to be 
> called on an `abstract` class. I was instead addressing the desire by another 
> list member to have classes declared `static` not also be able to be declared 
> `abstract.` That person made the argument that if 'abstract static` did not 
> actually have any effect then it should not be allowed by the RFC. 
> 

> What affect are we talking about?  If it is both `abstract` and `static` then 
> it would seem to me the only effect such a declaration could have would be to 
> disallow the calling of static methods using the named abstract static class, 
> e.g.:
> 
> abstract static class Base {
>static public foo() {
>   echo "foo() called\n"
>}
> }
> static class Concrete extends Base {}
> 
> Concrete::foo();  // works
> Base::foo();// fails
> 
> My only real argument for disallowing static method calls on abstract static 
> classes is that if we didn't do so initially we would never be able to 
> disallo

Re: [PHP-DEV] [RFC] Static class

2024-06-25 Thread Mike Schinkel
> On Jun 25, 2024, at 4:03 AM, Bilge  wrote:
> Nevertheless, the allure of early adoption is curious, and made me wonder 
> whether we could do both, just to support early adoption in a 
> backwards-compatible manner. 

And that is probably the best solution I've heard regarding this quandary.

It could potentially apply with other keywords in the future as well.  

#fwiw

-Mike


Re: [PHP-DEV] [RFC] Static class

2024-06-25 Thread Mike Schinkel
> On Jun 24, 2024, at 11:17 PM, Stephen Reay  wrote:
> 
> 
> 
>> On 25 Jun 2024, at 09:22, Mike Schinkel  wrote:
>> 
>>> On Jun 24, 2024, at 3:53 AM, Ayesh Karunaratne >> > wrote:
>>> - Why is it a class-level flag and not an attribute (similar to the
>>> `#[Override]` attribute in PHP 8.3) ?
>> 
>> From my perspective that would create much confusion among every PHP 
>> developer who has not committed to memory when to use `static` as a class 
>> keyword and when to use it as an attribute.
>> 
>> Given the concept already exists in keywords I would strongly argue that it 
>> makes no sense to introduce as an attributes in core PHP.  
>> 
>> Attributes are great for concepts new to PHP, IMO, but not for existing 
>> concepts already part of PHP implemented with keywords.
>> 
>>> On Jun 24, 2024, at 4:27 AM, Claude Pache >> > wrote:
>>> * The main purpose of the `abstract` keyword is to prevent a class to be 
>>> instantiated, which (in case of static class) is more semantically 
>>> described by the `static` marker. Beyond that, it just allows to declare a 
>>> method that, if implemented by a subclass, should have a compatible 
>>> signature. Most notably, it does not prevent the other static members of 
>>> the class to be used directly.
>> 
>> Given a primary purpose for being able to declare a class `static` is to 
>> signal intent, disallowing `abstract static` classes seems at odds with that 
>> goal.
>> 
>> Of course it is currently true that `static` methods of `abstract` classes 
>> can be called from outside a  class and its class hierarchy, so if we allow 
>> declaring `abstract static` classes then it would never in the future be 
>> possible to lock down calls of `static` methods to those `abstract` classes.
>> 
>> So IMO it would be better to disallow calling `static` methods from outside 
>> a declared `abstract static` class and its inheritance hierarchy as part of 
>> this RFC. That would be backward compatible since there are currently no 
>> classes that are declared in that manner.  Doing otherwise would force those 
>> who want to declare a class as both `static` and `abstract` to have to make 
>> a choice rather than being able to signal their full intent. Which brings us 
>> back to the "implied" vs. "explicitly declared" bifurcation I mentioned in a 
>> prior email.
>> 
>> BTW, I am assuming it is technically possible to disallow calling methods 
>> for classes declared both `abstract` and `static` without considerable 
>> difficulty in implementation and without creating a significant drain on 
>> performance. 
>> 
>> -Mike 
>> 
>> P.S. I would argue the same for `readonly static` properties, but as that 
>> seems those would require an involved discussion about the exact rules to 
>> implement I am demurring on that topic.
> 
> Hi Mike,
> 
> 
>> So IMO it would be better to disallow calling `static` methods from outside 
>> a declared `abstract static` class
> 
> Can you explain what you mean by this, or more specifically the "why". What 
> (implied wrong/bad) scenario are you trying to prevent, by disallowing a 
> static method on an abstract class to be called?
> 
> As you point out, it's already possible to call (public) static methods on 
> abstract classes, the same as it's possible to call (public) static methods 
> without instantiating a regular class.
> 
>  So why should static abstract classes be different? If the static method 
> shouldn't be called publicly, it shouldn't be public. Are you suggesting that 
> public static methods shouldn't be callable on *any* abstract class? If so, 
> this sounds like a huge BC break, and if not, it sounds like a confusing 
> "if-then-but-why" scenario.

Thank you for the question.

I was not specifically advocating `static` methods to be disallowed to be 
called on an `abstract` class. I was instead addressing the desire by another 
list member to have classes declared `static` not also be able to be declared 
`abstract.` That person made the argument that if 'abstract static` did not 
actually have any effect then it should not be allowed by the RFC. 

What affect are we talking about?  If it is both `abstract` and `static` then 
it would seem to me the only effect such a declaration could have would be to 
disallow the calling of static methods using the named abstract static class, 
e.g.:

abstract static class Base {
   static public foo() {
  echo "foo() called\n"
   }
}
static class Concrete extends Base {}

Concrete::foo();  // works
Base::foo();// fails

My only real argument for disallowing static method calls on abstract static 
classes is that if we didn't do so initially we would never be able to disallow 
because of BC.

In summary, my argument was really only about ensuring we allow "abstract 
static" declaration so developers can signal intent and also to address the 
objections of the other list member. But if given the option, I think it would 
be goo

Re: [PHP-DEV] [RFC] Static class

2024-06-25 Thread Chuck Adams
> On Jun 25, 2024, at 9:17 AM, Derick Rethans  wrote:
>
> Having read this thread, and the previous one from half a year ago, I
> will do so too. In short, we shouldn't be encouraging static classes as
> a bag of static functions, that ought to be just namespaced functions.

Which brings us back to the age-old problem that functions can’t be autoloaded. 
Me, I want first-class modules, but until we have those, I have to settle for 
classes in the meantime. Scala/Kotlin-like “companion objects” might be a good 
all-round substitute though.

Cheers,
chuck

Re: [PHP-DEV] [RFC] Static class

2024-06-25 Thread Derick Rethans
On Sun, 23 Jun 2024, Larry Garfield wrote:

> On Sun, Jun 23, 2024, at 6:10 PM, Bilge wrote:
> > Hi Internals!
> >
> > I am pleased to present my first 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!


> 
> For the record, as previously stated, I will be voting No on this RFC.

Having read this thread, and the previous one from half a year ago, I 
will do so too. In short, we shouldn't be encouraging static classes as 
a bag of static functions, that ought to be just namespaced functions.

cheers,
Derick


Re: [PHP-DEV] [RFC] Static class

2024-06-25 Thread Stephen Reay
Hi,

> On 25 Jun 2024, at 15:03, Bilge  wrote:
> 
> Hi guys,
> 
> On 25/06/2024 04:17, Stephen Reay wrote:
>>> Given a primary purpose for being able to declare a class `static` is to 
>>> signal intent, disallowing `abstract static` classes seems at odds with 
>>> that goal.
> What is the intent of `abstract static`? How is such intent different from 
> just `static`?

Sorry I should have been clearer. It isn't that `abstract` represents an 
intent, it's that adding `static` is mostly about conveying intent - and thus 
there's no *technical* reason that *any* existing class with only static 
members can't be marked as a static class, so why introduce an artificial 
barrier if that class happens to already be abstract?

It's already possible to have a class with only static members, that is 
abstract, and call the public static methods of it. It's also possible to have 
a class that partially implements an interface that has static methods on it. 
Unless your RFC is going to propose preventing calling static methods on *all* 
abstract classes it's a needless complication when there's no technical reason 
to do so.



>> I agree that the `static` keyword is a much better fit here, however there 
>> is one other aspect here that may come into it (as much as I prefer the 
>> keyword approach): the Attribute approach is backwards compatible (with a 
>> polyfill) to let code using this feature also run on previous PHP releases. 
>> Given that this is mostly intended as a way to signal intent about a pattern 
>> that's already in use, this may be significant for library authors.
>> 
>> Personally (as a library author) I don't think that ability is worth the 
>> weirdness of an attribute vs a keyword, but it may be more important for 
>> others who are voting, and I'd rather have the feature with slightly odd 
>> syntax rather than not at all.
> When I first saw the proposal to use an attribute instead of the keyword, I 
> thought it absurd, but this idea has now been entertained by three people, 
> and for the first time I have seen a compelling argument in favour of (early 
> adoption). I must admit, I was too quick to judge this one. I had not 
> considered that libraries will still not be able to use the `static` modifier 
> with classes unless and until they drop support for PHP < 8.4, which may take 
> a while! Of course, it is still of real benefit to first-party proprietary 
> projects whom have upgraded. Nevertheless, the allure of early adoption is 
> curious, and made me wonder whether we could do both, just to support early 
> adoption in a backwards-compatible manner. However, this would be 
> unprecedented and most likely not accepted; never before has the same feature 
> been implemented two ways just to appease early adopters. I think the best 
> compromise would be, for anyone so eager, to implement such support in 
> community tools, e.g. PHPStan. That is, it should be perfectly possible to 
> enforce the core semantics of the static class feature with a userland 
> attribute and the necessary logic in static analysis tools, provided the 
> library is well behaved and doesn't do anything too weird with variable 
> variables, references, reflection or unserialize() to deliberately circumvent 
> the restriction.

Yes it should be possible to use a user land attribute or phpdoc tag or what 
have, but that's *already* true. You've essentially just made a case against 
your own RFC - that it can mostly be done already in userland.

The entire appeal of a *builtin* attribute would be that it's something you 
could apply *now* (as in today, June 2024) and know that it won't *break* 
anything, while having some {compile,run} time benefits in later versions (e.g. 
enforcing static-only, and inability to instantiate).


Like I said, I much prefer the keyword syntax - but I also recognise that 
others may have different priorities in terms of supporting older language 
versions, which is why I think that aspect is worth consideration (perhaps a 
secondary vote, or an informal vote to gauge consensus?), because too many good 
RFCs get rejected over small details.


> Cheers,
> Bilge
> 



Cheers

Stephen 

Re: [PHP-DEV] [RFC] Static class

2024-06-25 Thread Bilge

Hi guys,

On 25/06/2024 04:17, Stephen Reay wrote:


Given a primary purpose for being able to declare a class
`static` is to *signal intent*, disallowing `abstract static`
classes seems at odds with that goal.

What is the /intent/ of `abstract static`? How is such intent different 
from just `static`?
I agree that the `static` keyword is a much better fit here, however 
there is one other aspect here that may come into it (as much as I 
prefer the keyword approach): the Attribute approach is backwards 
compatible (with a polyfill) to let code using this feature also run 
on previous PHP releases. Given that this is mostly intended as a way 
to signal intent about a pattern that's already in use, this may be 
significant for library authors.


Personally (as a library author) I don't think that ability is worth 
the weirdness of an attribute vs a keyword, but it may be more 
important for others who are voting, and I'd rather have the feature 
with slightly odd syntax rather than not at all.
When I first saw the proposal to use an attribute instead of the 
keyword, I thought it absurd, but this idea has now been entertained by 
three people, and for the first time I have seen a compelling argument 
in favour of (early adoption). I must admit, I was too quick to judge 
this one. I had not considered that libraries will still not be able to 
use the `static` modifier with classes unless and until they drop 
support for PHP < 8.4, which may take a while! Of course, it is still of 
real benefit to first-party proprietary projects whom have upgraded. 
Nevertheless, the allure of early adoption is curious, and made me 
wonder whether we could do both, just to support early adoption in a 
backwards-compatible manner. However, this would be unprecedented and 
most likely not accepted; never before has the same feature been 
implemented two ways just to appease early adopters. I think the best 
compromise would be, for anyone so eager, to implement such support in 
community tools, e.g. PHPStan. That is, it should be perfectly possible 
to enforce the core semantics of the static class feature with a 
userland attribute and the necessary logic in static analysis tools, 
provided the library is well behaved and doesn't do anything too weird 
with variable variables, references, reflection or unserialize() to 
deliberately circumvent the restriction.


Cheers,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Alexandru Pătrănescu
On Tue, Jun 25, 2024 at 1:00 AM Alex Wells  wrote:

>
> a static class member can never implement an interface's contract
>

Well, PHP is a weird one here compared to other languages

Interfaces can contain contracts for static methods and they are checked
just like usual non-static methods.
Example: https://3v4l.org/8cuXW

With late static binding, you can define static abstract methods and
basically do code reuse through inheritance.
Example: https://3v4l.org/pid7W

I'm not saying I would ever use such a thing, just that they exist and
others might find them useful so why build limits around it?
A limit is just extra code to maintain and make sure you use it
consistently.

I believe that a static class should have the principle of no allowed
instance and only static methods, without any impact on inheritance:
- There can be a static interface and a static abstract class
- A static class can extend a non-static class, or implement an interface
or abstract class as long as it does not require to implement a non-static
method.
- A static class can be extended only by another static class
- As static interface can be extended only by a static class

Basically, when a static class gets into the inheritance chain, all the
extending classes will be static and there is a guarantee that there will
never be an instance of that class.

Making sure a static class does just that, limiting the methods and
properties in it to only be static, will keep things simpler going forward
when thinking about interactions with other features.
Like readonly static class would not work right now, but it will work if
readonly will be implemented for static properties, and that should be
doable effortless.

Alex


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Stephen Reay


> On 25 Jun 2024, at 09:22, Mike Schinkel  wrote:
> 
>> On Jun 24, 2024, at 3:53 AM, Ayesh Karunaratne > > wrote:
>> - Why is it a class-level flag and not an attribute (similar to the
>> `#[Override]` attribute in PHP 8.3) ?
> 
> From my perspective that would create much confusion among every PHP 
> developer who has not committed to memory when to use `static` as a class 
> keyword and when to use it as an attribute.
> 
> Given the concept already exists in keywords I would strongly argue that it 
> makes no sense to introduce as an attributes in core PHP.  
> 
> Attributes are great for concepts new to PHP, IMO, but not for existing 
> concepts already part of PHP implemented with keywords.
> 
>> On Jun 24, 2024, at 4:27 AM, Claude Pache > > wrote:
>> * The main purpose of the `abstract` keyword is to prevent a class to be 
>> instantiated, which (in case of static class) is more semantically described 
>> by the `static` marker. Beyond that, it just allows to declare a method 
>> that, if implemented by a subclass, should have a compatible signature. Most 
>> notably, it does not prevent the other static members of the class to be 
>> used directly.
> 
> Given a primary purpose for being able to declare a class `static` is to 
> signal intent, disallowing `abstract static` classes seems at odds with that 
> goal.
> 
> Of course it is currently true that `static` methods of `abstract` classes 
> can be called from outside a  class and its class hierarchy, so if we allow 
> declaring `abstract static` classes then it would never in the future be 
> possible to lock down calls of `static` methods to those `abstract` classes.
> 
> So IMO it would be better to disallow calling `static` methods from outside a 
> declared `abstract static` class and its inheritance hierarchy as part of 
> this RFC. That would be backward compatible since there are currently no 
> classes that are declared in that manner.  Doing otherwise would force those 
> who want to declare a class as both `static` and `abstract` to have to make a 
> choice rather than being able to signal their full intent. Which brings us 
> back to the "implied" vs. "explicitly declared" bifurcation I mentioned in a 
> prior email.
> 
> BTW, I am assuming it is technically possible to disallow calling methods for 
> classes declared both `abstract` and `static` without considerable difficulty 
> in implementation and without creating a significant drain on performance. 
> 
> -Mike 
> 
> P.S. I would argue the same for `readonly static` properties, but as that 
> seems those would require an involved discussion about the exact rules to 
> implement I am demurring on that topic.

Hi Mike,


> So IMO it would be better to disallow calling `static` methods from outside a 
> declared `abstract static` class

Can you explain what you mean by this, or more specifically the "why". What 
(implied wrong/bad) scenario are you trying to prevent, by disallowing a static 
method on an abstract class to be called?

As you point out, it's already possible to call (public) static methods on 
abstract classes, the same as it's possible to call (public) static methods 
without instantiating a regular class.

 So why should static abstract classes be different? If the static method 
shouldn't be called publicly, it shouldn't be public. Are you suggesting that 
public static methods shouldn't be callable on *any* abstract class? If so, 
this sounds like a huge BC break, and if not, it sounds like a confusing 
"if-then-but-why" scenario.



I agree that the `static` keyword is a much better fit here, however there is 
one other aspect here that may come into it (as much as I prefer the keyword 
approach): the Attribute approach is backwards compatible (with a polyfill) to 
let code using this feature also run on previous PHP releases. Given that this 
is mostly intended as a way to signal intent about a pattern that's already in 
use, this may be significant for library authors.

Personally (as a library author) I don't think that ability is worth the 
weirdness of an attribute vs a keyword, but it may be more important for others 
who are voting, and I'd rather have the feature with slightly odd syntax rather 
than not at all.


Cheers


Stephen 



Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Mike Schinkel
> On Jun 24, 2024, at 3:53 AM, Ayesh Karunaratne  wrote:
> - Why is it a class-level flag and not an attribute (similar to the
> `#[Override]` attribute in PHP 8.3) ?

From my perspective that would create much confusion among every PHP developer 
who has not committed to memory when to use `static` as a class keyword and 
when to use it as an attribute.

Given the concept already exists in keywords I would strongly argue that it 
makes no sense to introduce as an attributes in core PHP.  

Attributes are great for concepts new to PHP, IMO, but not for existing 
concepts already part of PHP implemented with keywords.

> On Jun 24, 2024, at 4:27 AM, Claude Pache  wrote:
> * The main purpose of the `abstract` keyword is to prevent a class to be 
> instantiated, which (in case of static class) is more semantically described 
> by the `static` marker. Beyond that, it just allows to declare a method that, 
> if implemented by a subclass, should have a compatible signature. Most 
> notably, it does not prevent the other static members of the class to be used 
> directly.

Given a primary purpose for being able to declare a class `static` is to signal 
intent, disallowing `abstract static` classes seems at odds with that goal.

Of course it is currently true that `static` methods of `abstract` classes can 
be called from outside a  class and its class hierarchy, so if we allow 
declaring `abstract static` classes then it would never in the future be 
possible to lock down calls of `static` methods to those `abstract` classes.

So IMO it would be better to disallow calling `static` methods from outside a 
declared `abstract static` class and its inheritance hierarchy as part of this 
RFC. That would be backward compatible since there are currently no classes 
that are declared in that manner.  Doing otherwise would force those who want 
to declare a class as both `static` and `abstract` to have to make a choice 
rather than being able to signal their full intent. Which brings us back to the 
"implied" vs. "explicitly declared" bifurcation I mentioned in a prior email.

BTW, I am assuming it is technically possible to disallow calling methods for 
classes declared both `abstract` and `static` without considerable difficulty 
in implementation and without creating a significant drain on performance. 

-Mike 

P.S. I would argue the same for `readonly static` properties, but as that seems 
those would require an involved discussion about the exact rules to implement I 
am demurring on that topic.

Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Alex Wells
On Tue, Jun 25, 2024 at 1:56 AM Bilge  wrote:

> Hi Alex,
>
> If you wish to implement data objects, what part of the current proposal
> precludes you from doing so?
>
>
 None, but they both try to solve the same problem, so it's highly unlikely
that data objects would ever be considered if this RFC is accepted. And
while static classes fit better with lots of existing PHP code, data
classes (or a similar proposal) would bring more benefit to the table in
the long run, which is why I was hoping for an alternative solution to be
considered and/or discussed. I'm not planning to pursue the data objects
proposal further, but it was still worth mentioning so the internals are
aware of the alternatives to this RFC.


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Bilge

On 24/06/2024 22:56, Alex Wells wrote:

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`: 
.


Hi Alex,

If you wish to implement data objects, what part of the current proposal 
precludes you from doing so?


Cheers,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Alex Wells
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  wrote:

> Hi Internals!
>
> I am pleased to present my first 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
>


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Robert Landers
On Mon, Jun 24, 2024 at 10:22 PM Bilge  wrote:
>
> On 24/06/2024 09:27, Claude Pache wrote:
>
> Hi,
>
> Hi Claude! I really appreciate your feedback. Everything you highlighted is 
> an important point that will be included in the RFC!
>
> A general remark: I appreciate that a static class does not impose arbitrary 
> restrictions (like: implicitly `final`) on the class beyond what is 
> meaningful for staticness. On the other side, I don’t think that we should 
> support markers that are technically possible, but semantically meaningless, 
> like the `readonly` marker on class.
>
> Great point, `readonly` and `static` should be mutually exclusive and 
> generate a compile-time error, since `readonly static` properties are not 
> supported.
>
> Some more specific remarks:
>
> * In the intro: “A static class is a class whose members (properties and 
> methods) are all static”. One of the most important point is missing, namely: 
> It is meaningless for a static class to have instances.
>
> I thought that was covered off, but I'll see if I can word it better.
>
> * In the “Proposal” section, it should be stated explicitly that any attempt 
> to construct an instance, not only with `new`, but also with any of the 
> `ReflectionClass::newInstance*()` methods, or with `unserialize()`, or with 
> whatever other mean, shall fail.
>
> Great point, I'll include that detail. I think we're also missing a similar 
> detail with respect to dynamic properties, which should of course also be 
> forbidden.
>
> Should a static class be marked `readonly` or `abstract`? I think not, 
> because those have no real semantic meaning for static class; their effects 
> on static members are only consequences of their intended meaning on 
> non-static class:
>
> * Unless/until the `readonly` marker may be applied to static properties, the 
> only effect of such a keyword, is that it would prevent the creation of 
> static properties. I don’t know if that restriction is useful, but in case it 
> would be used for that purpose, it would be hijacking the `readonly` marker 
> for a something it wasn’t intended for.
>
> Agree, as above, we'll make them mutually exclusive.
>
> * The main purpose of the `abstract` keyword is to prevent a class to be 
> instantiated, which (in case of static class) is more semantically described 
> by the `static` marker. Beyond that, it just allows to declare a method that, 
> if implemented by a subclass, should have a compatible signature. Most 
> notably, it does not prevent the other static members of the class to be used 
> directly.
>
> I tend to find inheritance is not a very useful concept in static contexts, 
> but others have already pointed out that some have found uses for it. Due to 
> my lack of experience I cannot confidently say that `abstract static` has no 
> value, but you make a compelling argument. Happy to add a similar mutual 
> exclusivity prohibition for this keyword too, unless and until someone 
> protests it with an equally compelling argument to the contrary.
>
> The RFC says that a static class may extend a class not explicitly marked as 
> static, but with no instance member. This is not sound, because a class with 
> no instance members is not necessarily static. The most obvious example is 
> `stdClass` (which has no member at all, even if their instances may have 
> properties).
>
> Do you mean it is not simply sufficient for a class to be regarded as 
> implicitly static by virtue of the fact that it has no instance members? I'm 
> not sure I agree, but I may be missing something. If we extend `stdClass` 
> then we gain nothing, and our class so extending it can still be safely 
> marked static, can it not? Please elaborate so I might understand better.
>
> Kind regards,
> Bilge

Hey Bilge,

> Do you mean it is not simply sufficient for a class to be regarded as 
> implicitly static by virtue of the fact that it has no instance members? I'm 
> not sure I agree, but I may be missing something. If we extend `stdClass` 
> then we gain nothing, and our class so extending it can still be safely 
> marked static, can it not? Please elaborate so I might understand better.

I think it is sound in theory, but in practice, it will be a foot gun.
Imagine if you were to take my HTTP code library and make something
static from it. Later, I added an instance member. Now, when you
upgrade, everything starts crashing because of one little change
unrelated to your code.


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Bilge

Hi again Jordi,

On 24/06/2024 21:21, Bilge wrote:

Hi Jordi,

On 24/06/2024 13:22, Jordi Boggiano wrote:

On 2024-06-24 01:10, Bilge wrote:
I am pleased to present my first RFC: Static class 
.
Just one point of feedback: for clarity I think it would be good if 
it mentions that creating dynamic properties i.e. $this->dynamicProp 
= 'bar' would also throw at runtime (or even compile time if doable?).
Absolutely. I'll include a note about this in the RFC. 


On second thoughts, I don't think dynamic properties can apply at all. 
The notion of `$this` is a reference to an object instance; static 
classes cannot be instantiated, so the concept of dynamic properties 
simply cannot exist, and that's really all there is to it 😅 (unless I'm 
missing something).


Cheers,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Bilge

Hi Jordi,

On 24/06/2024 13:22, Jordi Boggiano wrote:

On 2024-06-24 01:10, Bilge wrote:
I am pleased to present my first RFC: Static class 
.
Just one point of feedback: for clarity I think it would be good if it 
mentions that creating dynamic properties i.e. $this->dynamicProp = 
'bar' would also throw at runtime (or even compile time if doable?).

Absolutely. I'll include a note about this in the RFC.
As for voting intention, it sounds totally reasonable to me, and while 
I don't see myself using it much I don't see a reason to be against 
it, so 👍🏻

Thank you! 🙏🏻

Kind regards,
Bilge

P.S. Thanks for Composer 🙂


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Bilge

On 24/06/2024 09:27, Claude Pache wrote:

Hi,
Hi Claude! I really appreciate your feedback. Everything you highlighted 
is an important point that will be included in the RFC!

A general remark: I appreciate that a static class does not impose arbitrary 
restrictions (like: implicitly `final`) on the class beyond what is meaningful 
for staticness. On the other side, I don’t think that we should support markers 
that are technically possible, but semantically meaningless, like the 
`readonly` marker on class.
Great point, `readonly` and `static` should be mutually exclusive and 
generate a compile-time error, since `readonly static` properties are 
not supported.

Some more specific remarks:

* In the intro: “A static class is a class whose members (properties and 
methods) are all static”. One of the most important point is missing, namely: 
It is meaningless for a static class to have instances.

I thought that was covered off, but I'll see if I can word it better.

* In the “Proposal” section, it should be stated explicitly that any attempt to 
construct an instance, not only with `new`, but also with any of the 
`ReflectionClass::newInstance*()` methods, or with `unserialize()`, or with 
whatever other mean, shall fail.
Great point, I'll include that detail.I think we're also missing a 
similar detail with respect to dynamic properties, which should of 
course also be forbidden.

Should a static class be marked `readonly` or `abstract`? I think not, because 
those have no real semantic meaning for static class; their effects on static 
members are only consequences of their intended meaning on non-static class:

* Unless/until the `readonly` marker may be applied to static properties, the 
only effect of such a keyword, is that it would prevent the creation of static 
properties. I don’t know if that restriction is useful, but in case it would be 
used for that purpose, it would be hijacking the `readonly` marker for a 
something it wasn’t intended for.

Agree, as above, we'll make them mutually exclusive.

* The main purpose of the `abstract` keyword is to prevent a class to be 
instantiated, which (in case of static class) is more semantically described by 
the `static` marker. Beyond that, it just allows to declare a method that, if 
implemented by a subclass, should have a compatible signature. Most notably, it 
does not prevent the other static members of the class to be used directly.
I tend to find inheritance is not a very useful concept in static 
contexts, but others have already pointed out that some have found uses 
for it. Due to my lack of experience I cannot confidently say that 
`abstract static` has no value, but you make a compelling argument. 
Happy to add a similar mutual exclusivity prohibition for this keyword 
too, unless and until someone protests it with an equally compelling 
argument to the contrary.

The RFC says that a static class may extend a class not explicitly marked as 
static, but with no instance member. This is not sound, because a class with no 
instance members is not necessarily static. The most obvious example is 
`stdClass` (which has no member at all, even if their instances may have 
properties).


Do you mean it is not simply sufficient for a class to be regarded as 
implicitly static by virtue of the fact that it has no instance members? 
I'm not sure I agree, but I may be missing something. If we extend 
`stdClass` then we gain nothing, and our class so extending it can still 
be safely marked static, can it not? Please elaborate so I might 
understand better.


Kind regards,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Jordi Boggiano

On 2024-06-24 01:10, Bilge wrote:
I am pleased to present my first RFC: Static class 
.


Just one point of feedback: for clarity I think it would be good if it 
mentions that creating dynamic properties i.e. $this->dynamicProp = 
'bar' would also throw at runtime (or even compile time if doable?).


As for voting intention, it sounds totally reasonable to me, and while I 
don't see myself using it much I don't see a reason to be against it, so 
👍🏻


Best

Jordi Boggiano
@seldaek - https://seld.be


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Andreas Hennings
> I am pleased to present my first RFC: Static class

To recap my opinion from the other thread:
I generally support the idea to have a label to slap on all-static
classes, to make that contract more explicit.
The goal is not to promote a specific use of the language, but to add
clarity to what already exists.

Since my last response on the other thread, I warmed up more to
namespaced floating functions, thanks Larry :)
At the same time I don't see static methods and all-static classes
fully going away soon, so I still support them having a label.
But...

>  Why is it a class-level flag and not an attribute (similar to the 
> `#[Override]` attribute in PHP 8.3) ?

I don't know that it needs to be a language keyword.
An attribute would be ok for me, or even just a doc tag with phpstan.
In fact maybe a feature request with phpstan could be a starting point.


> One question our razor cannot answer is whether static member declarations 
> still require the static keyword in a static class. Marking a class readonly 
> makes marking properties with the same optional, thus one might argue static 
> should follow suit. However, I opine it should not. Unlike readonly, which 
> typically applies to properties declared near the head of the class (by 
> convention) where the same mark is also applied, static members appear 
> throughout the full length of the class body. That is, it should be apparent 
> when jumping anywhere into a static class that its members are static, 
> without having to check the class declaration.

I prefer that the static keyword be required on the members.
This supports the common use case of incremental refactoring, where
methods are moved from one class to another, or a git merge where one
branch adds the class-level static keyword, while another commit adds
another method.


> We cannot remove features from a static class that would otherwise be present 
> in a standard class.

I think I get the intent of this statement, but I don't really vibe
with the wording.
I would say we should limit the scope of a modifier keyword to its essence.
And we should not remove features that are already being used in
classes that would naturally qualify for the class-level static
modifier.


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Claude Pache


> Le 24 juin 2024 à 01:10, Bilge  a écrit :
> 
> Hi Internals!
> 
> I am pleased to present my first 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


Hi,

A general remark: I appreciate that a static class does not impose arbitrary 
restrictions (like: implicitly `final`) on the class beyond what is meaningful 
for staticness. On the other side, I don’t think that we should support markers 
that are technically possible, but semantically meaningless, like the 
`readonly` marker on class.

-

Some more specific remarks:

* In the intro: “A static class is a class whose members (properties and 
methods) are all static”. One of the most important point is missing, namely: 
It is meaningless for a static class to have instances.

* In the “Proposal” section, it should be stated explicitly that any attempt to 
construct an instance, not only with `new`, but also with any of the 
`ReflectionClass::newInstance*()` methods, or with `unserialize()`, or with 
whatever other mean, shall fail.

-

Should a static class be marked `readonly` or `abstract`? I think not, because 
those have no real semantic meaning for static class; their effects on static 
members are only consequences of their intended meaning on non-static class:

* Unless/until the `readonly` marker may be applied to static properties, the 
only effect of such a keyword, is that it would prevent the creation of static 
properties. I don’t know if that restriction is useful, but in case it would be 
used for that purpose, it would be hijacking the `readonly` marker for a 
something it wasn’t intended for.

* The main purpose of the `abstract` keyword is to prevent a class to be 
instantiated, which (in case of static class) is more semantically described by 
the `static` marker. Beyond that, it just allows to declare a method that, if 
implemented by a subclass, should have a compatible signature. Most notably, it 
does not prevent the other static members of the class to be used directly.



The RFC says that a static class may extend a class not explicitly marked as 
static, but with no instance member. This is not sound, because a class with no 
instance members is not necessarily static. The most obvious example is 
`stdClass` (which has no member at all, even if their instances may have 
properties).

—Claude


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Bilge

On 24/06/2024 07:59, Alexandru Pătrănescu wrote:

On Mon, Jun 24, 2024, 02:15 Bilge  wrote:

Hi Internals!

I am pleased to present my first RFC: Static class
.


Hi! and good luck with the RFC.


Hi Alex, and thanks for your excellent feedback!

While I don't use static classes, I can see how this can be used by 
others.


It is my sincere hope that everyone will vote with similar empathy.


Feedback:

1. I agree that static classes may extend other non-static classes 
(that might have some static behavior).

To be clear, they must /exclusively/ have static members, not just /some/.
But I think that static classes should be extended only by other 
static classes, or at least for the first iteration of these feature.

This should be documented more in the RFC, no matter how it ends up being.
This is an interesting debate, and something we may end up doing. I am 
currently undecided if it would be better to enforce full static class 
hierarchy, but I could definitely be so convinced.
1.1 I think using a static class as a type should be considered an 
error, as there will never be instances of it if we consider all child 
classes will also be static classes.
Of course, this cannot be an error on php side given the class per 
file loading separation.
This is a very interesting point that I had not considered. I agree, it 
should be correct to forbid type hinting static classes. However, if I 
understood you correctly, we cannot actually implement that? My 
knowledge of engine internals is too weak to know the correct answer 
here. If it is possible, I think we should do it.
2. __set_state() is strongly linked to exporting a class instance as a 
valid php string, and is used to reconstruct the class instance upon 
execution.
Considering we forbid instances, we should not support __set_state(). 
If you think otherwise, please share an example how it can be used.


Thank you for catching this. This is strictly a mistake on my part. I 
have never used, or even heard of, __set_state() in my life. I was 
merely perusing the magic methods to make sure I caught them all and it 
seemed, at a glance, this might apply to static classes, but as you 
point out, if this indeed requires an instance then it does not apply. I 
will remove this from the next version of the RFC, which I shall publish 
imminently.


Many thanks,
Bilge


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Ayesh Karunaratne
>
> 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.


Hi Bilge,
I was reading the mailing list discussions, and I am glad you created the RFC.

Personally, I think this will be a useful feature. Just like we have
`readonly` properties and `readonly` classes, I don't see why we can't
have static methods. I also saw in the draft PR that it does not
require a lot of changes to the engine to have this.

I'd like to propose to add some more information and points addressed
in the RFC. This is of course merely a suggestion, but it's something
I was thinking when reading the RFC.

 - Why is it a class-level flag and not an attribute (similar to the
`#[Override]` attribute in PHP 8.3) ?
 - Can a subclass extend a static parent class without using the
`static` keyword in the subclass? This will avoid a lot of BC issues
if a library decides to declare classes as static.
 - Are there any opt-out mechanisms for subclasses?
 - Can you mark interfaces, abstract classes, and Enums as static?


Re: [PHP-DEV] [RFC] Static class

2024-06-24 Thread Alexandru Pătrănescu
On Mon, Jun 24, 2024, 02:15 Bilge  wrote:

> Hi Internals!
>
> I am pleased to present my first RFC: Static class
> .
>
>
Hi! and good luck with the RFC.

While I don't use static classes, I can see how this can be used by others.

I worked in big projects that used too many libraries, and when those
libraries have functions.php file, they pile up and loading the composer
autoloader can take a small dent on performance of each request.
Having functions grouped by a class that can autoloader instead of a file
is an advantage that should be spelled out as an use case.



Feedback:

1. I agree that static classes may extend other non-static classes (that
might have some static behavior).
But I think that static classes should be extended only by other static
classes, or at least for the first iteration of these feature.
This should be documented more in the RFC, no matter how it ends up being.
1.1 I think using a static class as a type should be considered an error,
as there will never be instances of it if we consider all child classes
will also be static classes.
Of course, this cannot be an error on php side given the class per file
loading separation.


2. __set_state() is strongly linked to exporting a class instance as a
valid php string, and is used to reconstruct the class instance upon
execution.
Considering we forbid instances, we should not support __set_state(). If
you think otherwise, please share an example how it can be used.

Regards,
Alex


Re: [PHP-DEV] [RFC] Static class

2024-06-23 Thread Bilge

On 24/06/2024 00:29, Larry Garfield wrote:

On the point of getting feedback on where people will vote now there's an RFC, I can only 
say with all honesty "Good luck." :-)  This is by far the biggest challenge of 
making an RFC: the lack of a meaningful sense of how something will be received before 
the actual vote.  Welcome to the club.

For the record, as previously stated, I will be voting No on this RFC.

--Larry Garfield


Thanks, Larry. I appreciate that, and on that point, I appreciate you 
being clear where you stand.


Cheers,
Bilge.


Re: [PHP-DEV] [RFC] Static class

2024-06-23 Thread Larry Garfield
On Sun, Jun 23, 2024, at 6:10 PM, Bilge wrote:
> Hi Internals!
>
> I am pleased to present my first 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

On the point of getting feedback on where people will vote now there's an RFC, 
I can only say with all honesty "Good luck." :-)  This is by far the biggest 
challenge of making an RFC: the lack of a meaningful sense of how something 
will be received before the actual vote.  Welcome to the club.

For the record, as previously stated, I will be voting No on this RFC.

--Larry Garfield


[PHP-DEV] [RFC] Static class

2024-06-23 Thread Bilge

Hi Internals!

I am pleased to present my first 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