On Mon, Nov 20, 2023, at 9:00 PM, Lanre Waju wrote:
I will have to disagree with everything you said:
I outlined what a static class would be: A class that cannot be
instantiated in which all members are implicitly static. We already have
static members, so please elaborate on the maintenance burden that
adding static to a class as that could help explain better, i mean what
feature doesn't have technical debt associated with it? The new JIT engine?
That's part of the point. Literally every feature added to a system (PHP or
otherwise) has some maintenance overhead associated with it. It may be small,
it may be huge, it may be worth it, it may not be worth it, but it's always
non-zero.
As for what a static class is, from your description I am understanding it to
mean this:
static class Foo {
public function beep(): string { ... }
public function boop(): string { ... }
}
Is effectively a shorthand for:
class Foo {
public function __construct() { throw new \Exception("You can't do that"); }
public static function beep(): string { ... }
public static function boop(): string { ... }
}
Much the same way a readonly class is. Is that understanding of the intent
more or less accurate?
3. It is entirely opt-in. If you hold reservations about using static
classes, you can simply choose not to use them.
This is a spurious and disingenuous argument, even if it gets trotted out
frequently on many RFCs. I'm not picking on you in particular here, but it's a
bad argument to use, period, 99% of the time, no matter who is saying it.
If you insist, Mr. Larry.
Cultural side note: At least in the US, where I am, "Mr. Firstname" is pretty much never
used except with some families that teach their children to use that with adults. It's not
necessary and kind of weird. "Mr. Garfield" if you want to be formal is fine, or just
Larry, or Crell, as that's the handle I use virtually everywhere and there are people who know me
as that more than as Larry. (I am not offended, just noting a cultural mismatch point.)
Similarly, if we add a static marker to classes, that means all future improvements to classes need
to consider "but what if the class is static?" Eg, there was discussion a while back
about `data` classes. What happens if you have a `static data class`? Is that a syntax error?
Does it work? If it works, what does "work" mean? What about sealed classes? Can you
have a sealed static class? What would that mean? Those are questions that would need to be
answered, because this feature exists.
Either i'm in an alternate reality where the data classes and sealed
classes rfcs passed, or I've just been straw-manned. Either way, is it
really that difficult to decide on as a community what a static data
class implies? We have already established that a static class means all
the members are static, but i can try to dumb it down for you if need be.
There is no need to dumb it down, just to read what I actually wrote. *Every* feature
added has implications for future features added. Data and Sealed classes are ideas that
have been floated but never to a full RFC, but may end up as an RFC in the future. They
were convenient examples of future work that would be impacted by adding a static keyword
to classes, as those RFCs would have to determine how to interact with static classes.
Maybe the solution would be simple, maybe it wouldn't, I have no idea. It is just an
example to show that the cost of adding a feature is never zero, and so the "if you
don't like it don't use it, so you're always wrong for voting against an RFC"
argument is nonsensical and disingenuous.
It impacts all users, too, because almost no one builds a 100% self-written
codebase anymore. 99% of projects are 80% someone else's code via Composer
packages large and small, which means every language feature they use, you need
to be aware of how to use. If some library has a static class as part of its
API, I am now forced to work with static classes, whether I like it or not.
If you had told me we were allowed to pull numbers out of our asses, i
would have mentioned that 100% of php users will benefit from this,
Including people like you who don't necessarily see the value in it. As
a user of a class, it shouldn't matter whether it's static or not, the
static members will be the same as using a normal class with static
members, in fact, people already simulate this in userland by making
__construct private and only using static members, does that impede your
ability to use such libs? How is this forcing you to use static classes?
The dev of said library(which no one is forcing you to use) would be the
one who made that call. After which it's your call to decide whether or
not the library suites you. I don't see any forcing here but do
enlighten me.
Funny you should mention it, in fact. One of the systems I maintain at work
currently is using an older version of Stripe's authentication library, which
is written as all static calls. That makes them unmockable. That sucks
horribly, because that means when our test suite runs we're sending *thousands
of auth calls* to Stripe, because there is no way to mock out that call with a
no-op, when we don't actually care what Stripe does in 99% of those tests.
We're currently in the process of upgrading to a newer version of the library
that has a proper instantiated service object instead of global static calls,
which will allow us to properly mock it, and save Stripe tens of thousands of
API hits per day and us probably multiple minutes on every test run. But it's
a slow process, and taking a lot of time/money to clean up.
*This is why static APIs are bad*. That's not just me making stuff up, this is
a well-understood principle around anyone who's done any serious work with unit
testing. It's easily the #1 argument people use against Laravel, which also
does a lot of static APIs and is, guess what, extremely hard to test properly
as a result.
A language-level feature that explicitly endorses and encourages those
all-static APIs (which is what is being proposed) would actively encourage code
like that Stripe library, which is wasting time, money, and network traffic for
us literally every single day. We should be discouraging that design, not
encouraging it.
The proposal is designed with the intention of improving code clarity,
reinforcing design principles, and establishing a clear and standardized
approach to expressing the intended usage of a class. While I advocate
for member properties and methods to be implicitly static, I am open to
understanding alternative viewpoints on why this might not be the
optimal choice.
Emphasizing:
reinforcing design principles,
Which is exactly the problem. All-static classes *are a bad design principle
that should not be encouraged*. They're a namespace cheat, not a good design.
They should be discouraged, not encouraged.
They could be used as a namespace cheat yes, they could be used wrongly,
but that doesn't mean it doesn't have any valid uses or make it
inherently bad. You remind me of the people that literally never use
inheritance because they read "inheritance over composition" somewhere.
Please elaborate more on why it's a bad design principle.
See above.
(sarcastic sniping removed)
I am still holding out for a productive conversation based on facts,
regardless, you are entitled to your opinions on the matter.
That static methods make unit testing harder and sometimes impossible is a
fact. That is not an opinion, it is an objective fact.
Language features that encourage making testing harder are bad features.
That's the long and short of it.
--Larry Garfield