> On 26 Jun 2024, at 12:51, Mike Schinkel <[email protected]> wrote:
>
>> On Jun 24, 2024, at 11:17 PM, Stephen Reay <[email protected] <mailto:[email protected]>> wrote:
>>
>>
>>
>>> On 25 Jun 2024, at 09:22, Mike Schinkel <[email protected] <mailto:[email protected]>> wrote:
>>>
>>>> On Jun 24, 2024, at 3:53 AM, Ayesh Karunaratne <[email protected] <mailto:[email protected]>> 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 <[email protected] <mailto:[email protected]>> 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 good to disallow calling static methods on
> abstract static classes if only to reserve the right to allow in the future vs. closing that door
> immediately. Still, that latter is not the hill for me to die on.
>
>> 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.
>
> Well, as previously stated, I think that would be confusing.
>
> Though I do see your reasoning for wanting it to be an attribute. However...
>
>> 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.
>
> I too am not convinced that the ongoing confusion would be better than the temporary need to
> support older versions of PHP with the same source file.
>
> Given that a build step could address the syntax there are certainly other new language
> features that require developers to bifurcate their libraries to support different versions, why
> make this one unique?
>
> That said, it could be a voting option for the RFC?
>
>
> -Mike
Hi Mike,
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 <checks notes> 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.
Re: attribute vs keyword,
Like I said - I'm not personally in favour of the attribute approach; I'm simply making
the point (playing devils advocate if you will) that by the very nature of how attributes work,
they're more friendly to supporting older versions of the language with a single code base. If
the general consensus is that it isn't a concern, great. But this wouldn't be the first
time we've seen a relatively minor syntax choice derail an otherwise useful RFC.
Cheers
Stephen