What the hell are Generics and would I want them in PHP?
Posted 31 May, 2017- About 6 mins to read
So everyone is talking about this hip “new” kid on the block for PHP: Generics. The RFC is on the table and a lot of people are getting all excited about it, but you don’t fully see the excitement? Let’s explore what it’s all about!
What is the use case of a Generic?
Generics is not something new. Statically typed languages like Java and C# have had them for ages. There are even some dynamically typed languages like Dart that implement them in their core. And even languages that don’t support Generics like for example Javascript can still support them with a 3rd party implementation, in the case of Javascript this would be Typescript.
The basic idea is that you can reuse a class that is statically typed with different typed parameters. OK, I understand that this might sound very confusing. So let’s check out an example:
|
|
As you can see, we are creating a Car
object with 2 parameters. The wheels and the engine.
Now this is all fine and dandy, but what do $wheels
and $engine
parameters represent? In this case it’s the amount of wheels and what engine it sports one would assume, as we send an integer and a string along.
But $car = new Car(‘pirelli’, true);
would be just as valid.
This is of course one of the typical things of a dynamically typed language. But if we want to add some more uniformity in our class we could, thanks to PHP 7 and types:
|
|
Now it’s impossible to create an invalid object thanks to the strict types. OK cool, let’s make everything strictly typed then!
But what if we want to create an object that’s both statically and dynamically typed? This sounds absurd but let me give you a use case. You want an object that accepts a parameter on creation but it needs to always return that same type of parameter on its return.
So for example when I do $myCar = new Car('honda');
and later $myCar->getEngine();
I want to be sure that what I get back from getEngine
is the same type as what I’ve put into the constructor (in this case a string).
OK show me this generic magic then!
Well… the thing is… at the time of writing, generics don’t yet exist in PHP yet. I know… what a tease. But luckily for us there is an RFC! So people are still loudly arguing whether or not they want to include generics into PHP and how it should look. But let us take a look at what the current proposed way of doing it is.
The use case described above could look like this:
|
|
|
|
Here we say, we are going to create a new Car, with 2 parameters; an integer and a string. You could according to the currently proposed RFC just send:
|
|
but I like the explicit version better for explanation sake. Next up is:
|
|
This tells the class about what variable types it supports.
And then we can use these virtual types just like normal types in the class.
So in this case the WheelType
will be an integer and the EngineType
a string.
It’s as easy as that.
That’s a use case that will never happen!
It is indeed a niche use case, but as PHP grows towards a hybrid of a dynamically typed and strictly typed language it does make sense to include some more features of strictly typed languages. While true, you will not use this everyday, there is no harm in having it in the language. It would however be handy for people that write logging or collection packages. Take this piece of code for example:
|
|
You can now reuse this collection for whatever you want, but you will always be sure getValues()
will return a collection of items that have the same type.
Even more fun is that you can instantiate a Collection like this: $collection = new Collection<Runnable >();
where Runnable
is an interface. This way you could have, for example, a collection that you are sure of only has items with values objects in them that conform to the interface. For example:
|
|
The <T is Runnable>
in this context would stand for: “you can enter whatever type you want here, but it has to adhere to the Runnable
interface.”
So what’s next? As I said before, the proposal is currently in draft. Once the proposal is finished it will go into a voting round and if there is a consensus about implementing it, it will be added, otherwise it’s back to the drawing board for Generics in PHP.
p.s. you can follow along how the RFC is going here