class BlogPostRepository extends BaseRepository<BlogPost> { ... }
$repo = new BlogPostRepository();
but the following would be very hard: $repo = new Repository<BlogPost>();
They write that the latter would need runtime support, instead of only compile time support. But why couldn't the latter be (compile time) syntactic sugar for the former, so to speak?(As long as you don't allow the generic parameter to be dynamic / unknown at compile time, of course.)
I wish we had typed arrays. Totally not gonna happen, theres been RFCs but I have enough boilerplate classes that are like
Class Option Class Options implements Iterator, countable, etc.
Options[0], Options[1], Options[2]
or Options->getOption('some.option.something');
A lot of wrapper stuff like that is semi tedious, the implementation can vary wildly.
Also because a lot of times in php you start with a generic array and decide you need structure around it so you implement a class, then you need an array of class,
Not to mention a bunch of WSDLs that autogenerate ArrayOfString classes...
This is the core problem with PHP for me.I love PHP and use it every day. Part of that is the strength and versatility of the arrays implementation (i.e. hashmap). However, the problem is always the fact that an array cant be typed.
IF they could just introduce that, it would solve 80% of user-land issues over night.
Is this not suitable for you?
More generally, it's weird to see a whole blog post about generics for PHP not even mentioning Hack's generics designs. A lot of thought and iteration went into this like 5-10 years ago.
See https://docs.hhvm.com/hack/arrays-and-collections/object-col... and https://docs.hhvm.com/hack/arrays-and-collections/vec-keyset...
But after some quick checking, I learned that Hack is still actively maintained, surprisingly.
What a weird take to base your current belief on something that happened more than a decade ago.
Not only the condition for Hack creation (speed, memory usage and strict type checking) have been fixed a long time ago since php 7.0
But also if you reach 10% of facebook scale, it doesn't matter what language you used, you will need to rewrite anyway.
Show me a company where PHP is the issue because they reached 10% of facebook scale, and what you're showing is a company that succeeded thanks to PHP. Applies to other language the same. Picking your stack based on "but what if I reach that scale" has to be the mother of all premature optimisations.
There are many others too. PHP not so much.
The answer to "why Hack" needs to be viewed in the historical context of "when Hack" and what was happening (or not) in the php ecosystem at that time.
Things have changed a lot since, in terms of performance, language longevity, ecosystem etc. Its a perfectly reasonable language to adopt for many orgs.
Unless I'm misunderstanding what this proposal (not finished artifact) is about.
At Facebook scale — with thousands of engineers shipping new code twice a day — slowdowns like these are even more problematic.
https://engineering.fb.com/2014/03/20/developer-tools/hack-a-new-programming-language-for-hhvm/But really while I was reading up on what generics are I went, isn't that just python, strongly typed but your functions don't have built in type checks.
For example, a mergesort algorithm works on any kind of array, as long as you can compare the elements in the array to each other. There's no point in re-implementing the algorithm for each kind of array. Yet, without generics, you'd need to do just that. At the same time, the generated code for sorting each different kind of array might need to be a little different - comparing strings and floats isn't the same assembly, for instance. So the programming language and compiler work together: you specify the algorithm once in a certain way, and the compiler can generate the right version of algorithm for each way that you need to use it.
There are many, many good reasons why you might want to work in a typed language, even though specifying the types is a bit of extra book-keeping; generics are one way to keep the pointless work down. Of course, if you can get away with a python script, there's no need to bother with all this typing business just yet, either.
It's rather the exact opposite. Parametric types are a way to properly type "deeply" instead of just the topmost layer. Just like inference, type parameters don't remove types.
> isn't that just python, strongly typed but your functions don't have built in type checks.
That doesn't really make any sense? Static types mean you don't have runtime type checks, since the types are known statically.
One of the most sought-after features for PHP is Generics: The ability to have a type that takes another type as a parameter. It's a feature found in most compiled languages by now, but implementing generics in an interpreted language like PHP, where all the type checking would have to be done at runtime, has always proven Really Really Hard(tm), Really Really Slow(tm), or both.
* The topic of the article is implementing generics at compile time, but this claims that PHP is not compiled.
* Type checking is orthogonal to compilation vs interpreter.
* Types are not checked at runtime. It is kinda the point of types that they are checked before code runs. Runtime checks are on values. You can reify types at runtime but this breaks a useful property of generics (parametricity) and it prevents the very useful feature of types without a runtime representation (often known as newtypes).
* If you want to use types in the colloquial "dynamic type" meaning as tags on values, and you also want to talk about generics (a feature that only makes sense for types-as-compile-time-properties) you need to be really careful in your terminology or confusion will abound!
I wish they would elaborate on what Really Really Hard(tm) means. From a high-level I believe everything they are concerned with has been researched as part of the work on contract by Robby Findler and collaborators. E.g. https://users.cs.northwestern.edu/~robby/pubs/papers/popl201...
As a community, we've seen enough untyped PHP spaghetti code in the early 2000s and never want to go back there.
That's a weird way to think about generics. Any class using generics effectively functions as a version of the class where the types are explicitly written out in all places. Instead of writing out one version of the class for every generic type, you write it out once and say which version you want to use at instantiation. You lose no safety, it's purely cosmetic and quality of life.
tobinfekkes•6mo ago
gloryjulio•6mo ago
C# is using reified generics where this information is preserved. List<String> is still List<String> after compilation
branko_d•6mo ago
This is very important both for cache locality and for minimizing garbage collector pressure.
svieira•6mo ago
metadat•6mo ago
https://openjdk.org/projects/valhalla/
There is an interesting article which mentions reification, but that's all I could locate.
How We Got the Generics We Have (Or, how I learned to stop worrying and love erasure)
https://openjdk.org/projects/valhalla/design-notes/in-defens...
svieira•6mo ago
> And as a consequence, C# can pack the value types directly in the generic data structure, instead of holding references to heap-allocated objects.
is what Project Valhalla is all about. (Java doesn't have a good reason for being able to do `new T` at the moment, but being able to treat a generic container as optimizable-over-structs is an explicit goal).
pjmlp•6mo ago
The project was announced in July 2014, hardly 20 years.
Also the reason they are still at it, is how to run old JARs withouth breaking semantics, in a Valhalla enabled JVM.
Had Oracle wanted to do a Python 3, Valhalla would have been done by now, however we all know how it went down, and Java 9 was already impactful enough to the ecosystem.
ygra•6mo ago
But if they want the List<int> use case to be fast they basically have to keep this information at runtime and will have to make changes to how objects are laid out in memory. I'm not sure there's a good way around that if you want List<int> to be backed by an int[] and `get` returning an int instead of an Object. This may or may not be available to developers and remain internal to the JVM in the beginning, but I think it's necessary to enable the desired performance gains.
They also state on the website: »Supplementary changes to Java’s generics will carry these performance gains into generic APIs.«
pjmlp•5mo ago
Probably MLton is the only implementation that actually does it the C++ and Rust way.
So lets see how far they go.
I always considered it was a mistake for Java to ignore what GC enabled languages were doing at the time, Eiffel, Modula-3, Oberon and frieds, which they naturally looked into given their influences, but it wasn't deemed necessary for the original Java purposes of being a settop box and applets language.
Now we have a good case of what happens when we tried to retrofit such critical features after decades of field usage, a lesson that Go folks apparently failed to learn as well.
kgeist•6mo ago
SPBS•5mo ago
> This is very important both for cache locality and for minimizing garbage collector pressure.
How is C# just not straight-up faster than Java then? Instead of both language punching around the same weight on benchmarks? Doesn't cache locality like, have a huge effect on performance?
actionfromafar•5mo ago
no_wizard•5mo ago
In many aspects C# is. I remember listening to a talk from Microsoft (admittedly) where using 100% latest features was on average faster than Java
PaulGaspardo•6mo ago
Gibbon1•6mo ago
I believe the terms reified generics and erased generics is the type sweaty donkey ball terminology you get for professional CS academics.
Sticking my neck out further.
Reified generics means the type is available at run time. In C# you can write if(obj.GetType() == typeof(typename))
Erased generics the type information is not available at run time. That's the way Java does it and it kinda sucks.
p1necone•6mo ago
Academic jargon isn't invented to be elitist, it's invented to improve communication.
(of course there's a good chance you understand this already, and you're just making a dumb joke, but I figured I'd explain this anyway for the benefit of everyone reading)
fuzzy_biscuit•6mo ago
Regardless, I recognize myself as the point of failure, but those names do strike me as academia speak, though better than some/many. <shrug>
klodolph•6mo ago
People describe a type system as “not well-founded” or “unsound” and those are specific jabs at the axioms, and people talk about “system F” or “type erasure” or “reification”. Polymorphism can be “ad-hoc” or “parametric”, and type parameters can be invariant, covariant, and contravariant. It’s just a lot of jargon and I think the main reason it’s not intuitive to people outside the right fields is that the actual concepts are mostly unfamiliar.
bawolff•6mo ago
The word reified dates back to the 1800s. It isn't the most common word, but it also definitely wasn't invented by the programming language community.
peterfirefly•5mo ago
skissane•6mo ago
To be more precise: in Java, generics on class/method/field declarations are available at runtime via reflection. The issue is that they aren’t available for instances. So a java.util.ArrayList<java.lang.String> instance is indistinguishable at runtime from a java.util.ArrayList<java.lang.Object> instance
mrkeen•6mo ago
In a good statically-typed language you don't need runtime type information. It could be a Void in the bytecode for all I care, as long as it behaves correctly.
> obj.GetType() == typeof(typename)
In a statically-typed language, this can be optimised away to a bool at compile time.
Gibbon1•5mo ago
positr0n•5mo ago
mrkeen•5mo ago
Jokes aside, what's the use case for not knowing what T is until runtime?
chuckadams•5mo ago
mrkeen•5mo ago
I don't buy that most polymorphism is dynamic.
No example of 'new T()' (which wouldn't be improved by static typing was given) so I got nothing else to say.
meindnoch•5mo ago