It has nothing to do with being “too hard”, and everything to do with not making sense to the type system. PHP is weakly-typed and heavily reflection-based (so everything is aware of it’s and each other’s type at all times).
Adding generics to PHP would make CS fundamentalists somewhat happy, but do nothing to change the fundamental design of PHP nor offer any of the traditional benefits that generics offer to strongly-typed and compiled languages. And would be a massive headache to implement, while bulking an already heavy VM implementation.
Exactly. The type system was never built for anything even slightly more complex. Its basically annotations for primitive types and classes. PHP has always had an weak type system, so adding generics will most likely never happen.
> Adding generics to PHP would make CS fundamentalists somewhat happy
PHP has really only one collection datatype (the infamous array), so having generics would be tremendously useful, as an example you cant return an typed array from a function, witch is just really bad.
For an counter example, Python managed to do this, while also being a dynamic language, although having a stronger typing than PHP.
Python managed to do this by not actually checking the types at runtime. If you declare a list[int] return type but you return a list[string] then nothing happens, you're expected to prevent that by running an offline typechecker.
PHP chose to check types at runtime. To check that a value is really an array<int> the runtime could have to loop through the entire array. All the types PHP currently implements are simple and cheap to check. For more elaborate cases you need an offline checker like PHPstan and comment-based type annotations. (PHPstan catches 99% of issues before the runtime gets to it so for my own code I'd prefer the Python approach with its cleaner syntax.)
The runtime checking seems the key difference, not so much the historical strength of the type system. Python's language implementation does very little typechecking itself and PHP's third-party offline typecheckers are respectably advanced.
Precisely. PHP has tools for this too, but lack the syntax. Right now you need to to all typings in comments, and thats just as bad as jsdoc was in 2005.
This could be the way PHP could go, they just need the lexer to handle types, and not do any runtime checking at all.
But i guess that goes against what the php devs want, but it sounds so wasteful, to typecheck the same code time after time even if it passed some sort of initial "compile time step".
The current amount of typechecking might be a net efficiency improvement AFAIK. It provides a hard runtime guarantee that variables are certain types while Python has to check whether something is supported at the last possible moment. But I don't know how much use the optimizer makes of that.
Python is not (usually) run like PHP. Python programs (like most other languages) "run", compared to PHP where you in 99% of all cases instead "execute". (run = the program is running for a long period of time, and execute = run/die immediately).
This subtle difference has huge implications. You could in theory have an "compile step" in. Python, but in PHP you really cant as the program is never "running".
Python built syntax for types / generics etc. Its actually a quite capable typesystem (im not a python developer, but use python on some occasions). Python then has tools for static typechecking that can be run outside execution.
This means that if python would do actual static typechecking on runtime it would be nothing more than wasted cpu cycles.
Thats why python opted for the syntax only, as its basically zero cost. In php land the typechecking is done on EVERY execution, even if the code was unused. (a void functions that has an int param, but gets passed an string, that just discards the parameter). Even worse, a type error thats not executed wont be caught by every execution.
In short PHP typesystem is just runtime checks for primitives / classes and wont catch errors where not executed. Its like the worst of both worlds.
> you cant return an typed array from a function, witch is just really bad.
Why is it bad?
In particular, why is it worse than not being able to declare a typed array in your current scope? (I understand the basic argument in favor of typed arrays, but I also understand why PHP would choose not to go that route; I'm not sure I see how it's worse to not be able to return one from a function, given that they don't exist elsewhere.)
I often return some collection of types in an array eg [User, Config]. Right now my return type is just "array". To get this to work i need to build yet another wrapper class and all that, and thats just wasteful and totally unnecessary.
A even more simpler example is An array of some sort of Item. I cant return array(Item), but i only can return an array.
The parts thats not working is if i return a plain "array" i can then put whatever inside it. Its basically the same as "any" but wrapped inside an array.
But that is no different than if you created the array in that scope.
So, again: Why is it "really bad" that you can't return a typed array from a function? What is worse about that than not being able to create a typed array in the current scope?
Also: What, exactly, about that is "not working"? As I said above, I understand the basic arguments about typed arrays; they're conceptually equivalent to weak/dynamic types. And there is value in having strong and static types. But it's hardly a showstopper not to, and PHP works just fine even if you don't use any. It just...makes it easier for us, as programmers, to make mistakes.
So to say it's "not working" simply because it's possible to add elements to the array that don't match the types you want seems like an exaggeration.
PHP typing is most definitely stronger than python overall.
Yes array is the evil collection type of everything, but that's how it's meant to work. Array is the quick and dirty 'throw everything in there' thing. PHP has classes and they're very full featured and offer lots of type safety - use those.
I mean from a static analysis perspective - type annotations in PHP actually do stuff, and you can type annotate pretty much everything. And people actually do it.
Also, you can just flip on strict typing in PHP, and you should know that.
Strict types determine whether a function accepts a variable of a certain type, casts it, or throws a TypeError. It does not affect int + string operations or anything else really
Kind of but not really. Even without strict types, functions will throw a type error if you give them the wrong thing for almost all types, except primitives, which will be automatically coerced. Strict types turns that coercion off.
Really, that's probably enough for a lot of cases, because PHP doesn't have operator overloading. Yes, you can add '10' + 10 and get 20, but not if either of those go into any function. If you have a function that needs to do string stuff, you take string stuff in, and you don't have to worry about string operations or coercing ints or anything.
You are probably talking about this: https://stitcher.io/blog/generics-in-php-3 . If I remember correctly, the author claims it will either cause runtime overhead or extreme memory overhead. The best solution is to introduce a typed superset of PHP like TypeScript was done for JavaScript.
TLDR: The PHP compiler isn't really suited for the job, it would introduce a lot of complexity to an already complex codebase and the memory/performance hit would be substantial.
Yup, this was pretty much what i recalled. The typesystem, while being incredibly "unintelligent", somehow still is so complex that generics are not going to happen.