Hacker News new | ask | show | jobs
by pdenton 1670 days ago
Having used PHP since version 4 (20 years ago), I can say with confidence that its had its peak. Everything new added since 7.4 is just fluff or bloat. Fixing long standing bugs and performance improvements is fine, of course. But everything new they introduce adds to the pile of warts that's PHP. I highly regard those that try to improve it, but with the current direction it'll remain the colloquial example of how not to design a programming language.
5 comments

> Everything new added since 7.4 is just fluff or bloat.

The 7.4 did not finish the type system work. Docstrings were still needed for basic type hunting.

I found that php8 has brought numerous features that will formalize things I am currently doing as hacks and workarounds.

Exceptions as expressions--I can stop writing, `$x = $context['x'] ?? ThrowWrapper::missingValue('x');`

Named Arguments -- I use a hacky diy `Reflection` heavy version of this for an RMI/dispatch where json key-vals mapped to function params.

Static return type and union types -- I have been relying on PhpStorm docstring hacks for this sort of type-hinting.

`readonly` will be very helpful to express performant, immutable classes. I have a number of classes that are immutable-by-convention, trusting the caller not to monkey with the internals. (The idiomatic way to do this, `$immutable->getAttr()` is too costly in tight loops compared to `$immutable->attr`)

PHP still has lots of warts (function calls why you so aspensive?!?!?) but I keep being pleasantly surprised by how good of a tool it's evolving into.

Thank you. I don't need any of those, though. $immutable->getAttr() is easy to mock, easy to override, and allows for custom behavior (e.g. return clone $this->Attr).

Static return type, useful but since I use interfaces for everything it's not really needed. Union types, also not really needed because either 2 interfaces share a common ancestor or I'll have separate methods for different types. But most of the time, I encapsulate things behind interfaces that do one thing, so having different methods per type can often be avoided.

Named arguments are a pain for me since now I can't change parameter names anymore. This is particularly annoying with different coding styles in dependencies vs my own code. My code ends up not conforming to the coding standard that I've used since it was introduced (PSR-2R).

Exceptions as expressions is a nice to have, but exceptions in general are a thing to avoid doing. Not that things can't go wrong, not that chugging along in the face of errors is good, of course it's not. But if you have a lot of exceptions in your code, that's a smell of bad design. I've got 13 different exceptions used 20 times in total, over 4683 LoC on my current project. Mostly, whenever one of them is triggered, whatever I changed last was incomplete and led to an inconsistent configuration.

That said, your use case for PHP is probably very different. Especially since I don't care much at all about performance anymore. I used to, but CPUs are so much faster nowadays and PHP itself has improved.

I'm not sure the spread operator [or any form of apply()] is a good idea in a programming language. You've just added another bit of indirection that isn't even explicit, but is based on whatever the runtime state is. This is anathema to any sort of structured programming. The inferred state is just hand waved because any mismatch is pushed, as an incidental side effect, into the next function.
It wasn't designed, it was evolved. The author said as much. Evolution seldom produce clean designs.
JIT compilation certainly isn't fluff or bloat.
FFI too