Hacker News new | ask | show | jobs
by anttihaapala 580 days ago
Oftentimes many of the significant new PHP features are to fix the shortsighted implementation in the previous ones - for example this method chaining with `new` - there was precedent already, C++ got it right well before PHP even existed and with the very same arrow operator that PHP borrowed (and so did Java and JavaScript with .), so the question is why did PHP have to get it wrong at first and for so long.

Another pet peeve of me is that the global namespace is littered with these utility functions that should be easily composable or maybe be methods on the objects themselves - and looks like PHP 8.4 adds four more `array_*` functions. For comparison, Python's builtin namespace has a total of 71 functions and a couple of exception classes. PHP's builtin namespace has more functions for dealing with arrays and now 58 of those are prefixed with `array_`.

4 comments

The global namespace change would break everything. It’s unlikely they would ever do something like that.

It’s hard to build on a language used by so many, when you can’t modify the base. Python decided to do 2.7 vs 3 and fragmented the eco system terribly.

They could help by not adding any more cruft to the global namespace.

Adding any globals should be a carefully-considered change. User-defined functions are global by default, and although there are (now) much better ways to write PHP libraries, I can absolutely see some old library defining array_find (one of the new global functions in 8.4) in an incompatible way and breaking new code that attempts to use the built-in function.

Sure, you can’t touch the existing pile of globals, but at least stop pouring fuel on that particular fire…

That would be some really old library. Already in 2012 when Composer was released there was PSR-0 and today almost all libraries are Composer managed and using a namespace following PSR-4 which itself is ten years old. A library that old would almost surely not run on PHP 8 unchanged anyways.

Surrendering the global namespace to the language is not so bad an idea.

Suppose I want to add some new code to an old website? Or I want to gradually upgrade an ancient code base - twelve years is not so old for PHP, when ancient frameworks like Wordpress are still alive and kicking.
If we hitched language development on Wordpress we would still be on PHP4 as they refused to join gophp5 some seventeen years ago.

Again, an ancient enough codebase which contains a library using array_find will need enough upgrades to run on PHP8 much less PHP8.4 the change from array_find to something else is the least of your worries.

Seriously? 2k results for array_find in PHP on GitHub: https://github.com/search?q=array_find++language%3APHP&type=.... RFC authors (https://wiki.php.net/rfc/array_find) explicitly noted over 600 hits for definitions of array_find, around 30% of which are not false positives - that is, there's a good possibility that there are 200+ implementations of global array_find in just open-source projects.

First page hits https://github.com/hawind/gdoo/blob/master/app/Support/helpe..., a PHP app last updated just two years ago (140 stars, 63 forks) which only supports PHP 8.x. Implementation is thoroughly incompatible with 8.4's array_find.

There are so many more examples. Lots of the hits are from codebases that have seen updates in the last few years. Many more are plugins or other addons for PHP frameworks or apps which are still widely used (WordPress, phpBB, etc.).

Then you use your IDEs refactoring feature to rename your version of the function, or put it into a namespace, and you’re done in about 12 seconds.
I think the bigger issue is that these lessons have already been learned. However, PHP (Personal Home Page) was not created carefully by someone to become a fully fledged language. It grew into that role organically which is why it has so many warts in hindsight.
I don't get your issue with builtin utilities.

The design philosophy of PHP is to include whatever common methods would otherwise be in a popular library. (PHP actually began more as a library than as a language.) This differs from, eg, Python, but doesn't hurt.

The decision not not to make methods on the objects, but to include everything in the main namespace (so array_walk instead of Array.walk or Array()->walk etc) is another function of the same philosophy. It may not fit your idea of cosmetics, but there is nothing wrong with it.

On the other hand, I would love if PhP gained chainability ([].array_map.array_find()) and then the names would be a pain. If that ever happens there are solutions.

There is a RFC on it (https://wiki.php.net/rfc/function-composition) which I'd love if it made it through. Until then Crell's FP library is a good option (https://github.com/Crell/fp).
Whats the problem with global namespace littered with utility functions. Do they get in the way? They hurt you? They whisper in your ear? Or with the badly named functions? Or the type juggling? Do they eat your soul?
It could be much easier for user defined functions to collide with standard functions, especially when it happens unintentionally.

Someone else creates a function named array_something in the namespace. Maybe it already exists in earlier versions, maybe it happens to collide with one of the four introduced in 8.4. This function is accessible to you in the current scope. Now, you try to call the function like the way it is defined in the standard library. You get a very confusing error and spend 10 minutes trying to figure if it is you or PHP that is hallucinating. Turns out you have been inadvertently calling that other user defined function. The other user may be completely unaware of the fact that they created a function with naming collision.

To combat this, you need strong IDE help including static type checking, which is not always there for everybody. And it still doesn't help with cases where the user defined function collides with a new standard function.

Most "modern" languages have very few built-in functions in the global namespace. Another example is Go. Correct me if I am wrong, but I believe there is 0 function in global namespace in Rust. println! exists but that's a macro. In other words, the example I mentioned just never happens with these languages.

Not to mention the long list of junk you see in IDE when you type "array_".

I guess you haven't written much MATLAB.

Rust namespaces everything in the standard library to std:: or core::, and has a clear distinction between them.

However, it does implicitly include the entirety of the std::prelude namespace (https://doc.rust-lang.org/std/prelude/index.html) into every source file, as well as including every macro directly exported under std:: (including println!). This enables the unprefixed use of things like Result, Option, Some, Send, etc.

The prelude and std:: macros are the closest thing that Rust has to a global namespace, and even they can be disabled in crates that specifically request it.

This would be a valid point 20 years ago.

PHP functions can be namespaced. I can just write myLib\array_find, otherLib\array_find. You choose what implementation you want when importing. IDE will pick the correct one.

So, zero chances of collision.

Read my comment and all previous comments again.

Don't write such meaningless words and waste your and other people's time when you don't even understand what people are talking about.

Your previous comment makes little sense and your reply is just angry and explains nothing.

A tool to avoid collision was introduced decades ago. This tool was made proeminent by the language and the ecosystem (PHP-FIG, frameworks, books, popular PHP celebrities).

You literally have to had stopped programming PHP more than a decade ago to not understand namespaced functions.

https://phptherightway.com/#namespaces

This problem of collision was seen miles ahead, and people were gently introduced to the idea that the global namespace belongs to PHP builtins and you should not pollute it even further.

I would say it is consensus for the PHP community that if your code broke because you defined array_filter globally before 8.4, then your code sucks and you don't know PHP.

What is the practical difference between a prefix and a namespace?