> On Jun 27, 2024, at 12:09 AM, Stephen Reay <php-li...@koalephant.com> 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 > <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 <php-li...@koalephant.com > <mailto:php-li...@koalephant.com>> wrote: > > This is an example of code that works today (and all the way back to 5.0): > https://3v4l.org/4EKo2 <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 <checks notes> 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 methods for their `abstract static` classes access to `@internal docblock` — which I argued against elsewhere in this thread — and let Hyrum's Law take over, OR do we enable them to disallow calling those `static` methods from the `abstract` class itself? More importantly, IF we do not immediately disallow calling `static` methods on `abstract static` classes then we will never be able to disallow in the future, because of BC. But on the flip side we could later open them up for calling if we found the limitation to be problematic. > or if it applies the change everywhere it's going to be a BC break. And to be clear, I am against BC breaks in almost all cases. So bringing that up between us is moot. All that said, if you tell me "I don't care about closing the door on being able to disallow developers from calling static methods on `abstract static` methods because prior to `abstract static` classes `static` methods could be called on `abstract` classes in the past" I will respect that, and as I said above, it won't bother me. My only reason for persisting is to ensure that the argument I was making was understood before it was dismissed. -Mike [1] Ignoring there were technical issues with allowing untyped to be readonly, which could have been gotten around somehow if the consensus was "They must be able to untyped."