Car park

What the hell are generics and would I want them in php?

Posted Tue May 30 2017

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 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 type parameters. OK, I understand that this might sound very confusing. So let's check out an example:

Yes I know, I’m explaining OO stuff with a car class. I know it’s super cliche, and I’m normally not a fan of getters, but just roll with it.

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 number 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:

As you can see, we now have brackets! So first up is this:

$car = new Car<int,string>(4, 'Honda');

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:

$car = new Car(4, 'Honda');

but I like the explicit version better for explanation sake. Next up is:

class Car<WheelType, EngineType>

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 every day, 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 with how the RFC is going here

Hey thanks for reading!

Hope you enjoyed this post. There is no comments section here, if you've ever seen the YouTube comments section you'll probably understand why. If you have any remarks or comments on this topic, you can find links below to social media discussions

Bird's eye view of a landscape

A bird's eye view on API development

Posted Sun Nov 15 2015

So you want to build a web API. You have to start somewhere, why not here

Continue reading
max verstappen formula 1 car

What performance tricks actually work

Posted Mon Jul 23 2018

We've all been there before, you submit a pull request and moments later you get a comment like: ''Hey you should use a native function here, they are so much faster'' or ''You can declare this final, that way we save some processing power''

Continue reading

Atomic commits: telling stories with git

Posted Wed Dec 06 2017

These days I’m all into atomic commits and it really made my work beter. Never heard of that concept? No worries, let me introduce you to it

Continue reading