It’s been ages since last I wrote something here. I’d been planning to do a follow-up on my “Traits are Evil” post, which for some reason still gets quite a lot of traffic. The main reason why I didn’t though, is what I’m writing about now. That post, in case you missed it, was about PHP’s recently added feature: Traits. I wrote down a number of fundamental problems with their implementation, and intended to write a follow-up listing a few valid uses.
The reasons behind this are twofold: PHP is a language that has a long history of being abused by people who don’t really understand the intricacies of programming. I predicted (and still do) that traits will be wildly abused.
The other reason is simply this: I’ve not written any PHP in over a year, and it has been bliss.
Do I hate PHP now?
No, not really. I hate some aspects of the language: with the best will in the world, it’s a right mess. Rather than cleaning up some of the nasty inconsistencies, the developers seem to be mainly concerned about adding yet another operator (like the spaceship operator), constructs like traits, and things like “Throwable” vs “Exception” distinctions. Of course PHP made some changes for the better: scalar type-hinting, an AST (Finally!), and another (significant) step forwards in terms of performance.
Looking at the things that annoyed me, compared to things I thing are genuine changes for the better, I have to say: too much time is being wasted on what could be considered as “eye-catching” gimmicks, whereas the serious work that needs to be done is taking ages. Last I checked, a standard PHP installation ships with 3 MySQL extensions, one of which is deprecated. The internal string handling still isn’t UTF-8 (remember: PHP6 got dropped because nobody was helping the poor soul who was working on that).
In essence: the serious work takes too long, and the language is getting more and more bloated with syntactic sugar. I wouldn’t at all be surprised if, within a year or two, JS-style arrow functions get added to the language. Not multiple return values, but arrow functions.
So as you can tell by now, I do critique the language, and acknowledge the steps it made in the right direction. However, why did I jump ship right when PHP7 was gaining traction? There’s two main reasons for this. One is a frustration that has been steadily growing over the years: The community. The other one is simply this: I was given an opportunity to work in a new language, that I’d been interested in for a while.
What? Muh Community?
Let’s unpack the first reason: “the community” was starting to get to me. PHP being a stupendously forgiving language with such a low barrier of entry, is a language that is used by absolute dipsticks. The percentage of people writing PHP who are capable of writing actual, decent code in it is so disproportionate. If the “normal” ratio is about 1 in 3 are capable of writing good code, in PHP that ratio is closer to the 1 in 30.
To quote the old, but still often referred to post: PHP: A fractal of bad design
I have never met a PHP developer who can do the same with PHP. But I’ve bumped into plenty who are quick to apologize for anything and everything PHP does. That mindset is terrifying.
This is not an 100% accurate observation in my opinion. I very often found myself apologising for what others were doing with PHP. I never claimed PHP is a perfect tool, I’ve never tried to down-play its messiness. It’s flawed, and everyone knows it. My position has always been: in the right hands, you can write a decent code in PHP, it’s just that the language doesn’t reqiores you to be a better developer. Hence 90% of the PHP out there in the wild is truly awful.
After seeing people who’d been writing PHP for years (over a decade, even), who were still writing “classes” relying on (super-)global variables, I realised this is probably PHP’s worst problem. If they rewrote the Zend engine and made it as strict as it should’ve been to begin with, probably over 75% of the sites running PHP would stop working. This means that, anywhere you end up working on a PHP codebase, it’s highly likely you’ll feel like you’ve just accepted a job cleaning up all cow dung in the world with chop sticks.
I’m writing Go now
Yes, I’ve made the switch to golang. I’d been looking at golang for quite some time. It’s concurrency model really appealed to me, the syntax was a bit odd at first, but I was genuinely amazed at how long that lasted (about half an hour).
It’s no secret that I’m one of those people who like the simplicity of a language like C. Golang is in many ways quite similar. As a language, there’s very little to it, really, but the language is as a whole unbelievably expressive. People rip on certain aspects like: how the language and its toolchain are so opinionated. Well, that’s really a good thing: the more uniform the code is, the easier it becomes to read someone else’s code. I can simply look up the source of a package, and within minutes look at how something is implemented and work out how to get the most out of it.
The debugger isn’t quite there yet. That’s an accurate critique. But then Xdebug wasn’t exactly a gem either (impressive though it was). The built-in debugger that shipped with PHP5.6 is something I have not enough experience with to judge. That said, the debugger is being developed still, but at the same time tracing and profiling is stupendously easy to do.
The main things that got me interested in Go, however, are simply the selling points: Its UTF-8 support, concurrency model, speed (both runtime and compiler), its versatility (CLI tools, micro-services, text processing, …). In fairness, I’d only consider golang my go-to language when it’s a CLI tool or something networking related. I wouldn’t consider golang a language that is a valid choice for GUI development, for example. Having said that: some projects are doing just that, and they seem to be pulling it off.
The things I miss (from the PHP days)
I know, after saying I like go, and criticising certain aspects about PHP, I have to admit there are some things I well and truly miss. The main thing is composer. I subscribe to what Fabien Potencier said about PHP/Composer: PHP has one of the best dependency manager of any of the FOSS languages. Ruby? Absolutely not. NPM? Yarn? Do one. Pip? Are you having a laugh? Composer isn’t perfect, but still: show me a composer.json file, and I’ll install all dependencies (RAM permitted) in about 10 minutes. If I give you a project and you see a Rakefile, there’s a good chance it’s not going to be so effortless.
Golang wasn’t originally intended to require dependency management for reasons I’ll get to in a minute. It does have vendoring now, but the pacakge managers are no where near as full-featured or mature as composer. One of the reasons for this might be down to the fact that there’s still quite a lot of different dependency managers being worked on, and used in the wild.
Another thing I do miss is simplicity. Not from a language perspective (God no). The development toolchain for golang is a bit more complex. You inevitably have to be more aware of things your average PHP developer is blissfully unaware of. Most PHP developers have no clue how to get metrics from the stuff they write. If you wite a service in golang, however, you’re not just running your code on a runtime/interpreter that is running on a server on a server. Your binary is, most likely, running in a scratch container (ie it’s completely empty apart from your binary). You’re creating a simple server, that handles certain endpoints, and should spit out logs in the desired format, and you should be able to extract, from that container, all sorts of metrics for monitoring.
Is that something I hate doing? Absolutely not, but sometimes I think my life as a PHP developer was a lot simpler. I didn’t have to know how to set up reverse proxies in AWS, people could discuss HA and statefullness elsewhere, because it hardly ever affected my work. Not so much when you’re doing Go.
Things I would miss (Should I ever go back to PHP)
Ugh, where to start. I’d miss the ability to start routines whenever I feel like it. I’d miss silly things like the defer keyword. Strong typing is also high on the list of things I’d probably miss from day one. I’d also miss the idea of pointers, the ability to composition (instead of inheritance) flexibility that Golang brings to the table. As a part of that, the implicit interfaces is another thing I don’t want to do without.
Mutliple return values is another really nice thing to have, including the much hated “error” type. Many people dislike the golang error type (demanding an exception-like thing instead). After having used it for over a year, I’ve started to grow rather fond of the error type, which is actually a really simple interface.
The one thing, though, that I’d miss most of all is the incredibly powerful type system. Whilst strongly typed, I can easily pass around a value that is no different than your ordinary int, but I can use that value as if it’s an error, a Stringer, an int, … And whatever else I want to do with it.
This means I can have a server “object” that is just a simple empty string, if I so desire.
Add to this the ability to compose existing types into a new object, and therefore combining interfaces, you have something that is so much more powerful than classic inheritance. True, it does require a change in mindset, and it does trip you up at first.
What else has changed?
The most drastic change I made was my choice of editor. When I was writing PHP I used Jetbrains’ PHPStorm, like most people do. Just over a year ago, they did have a fairly decent Golang plugin, and the EAP program for Gogland had just been announced. However, I found myself let down a bit by those editors. I switched to VSCode for a while, and found it decent. That is until I found out about the vim-go plugin.
Now hang on, I won’t start ranting and raving about how great vim is, and why you all should switch (which you should, but that’s besides the point). What I wanted was an editor/tool that fits the golang toolchain. To me, it still doesn’t make sense to use a heavyweight, Java-based editor to write golang. Couple that to the fact that I already was an occasional vim user, and vim-go at the time offered the most complete golang IDE, I decided to set it up, and put the effort in. After just 2 weeks, I worked out something drastic will need to happen for me to find another editor.
So in conclusion
I’ve now been PHP-free for over a year, and I can safely say it’s been really enjoyable. I’ll always feel like I owe a certain debt to PHP. After all, it was the technology that got me my first job in tech, it was PHP that got me to move to another country. Having said that, if you don’t develop on a personal level in this industry, you will be deprecated.
It sometimes feels very much like being a recovering alcoholic, though (hence the title). On the one hand, there’s a ton of things I’m not having to deal with anymore, which is unbelievably nice. Weirdly, I now hear what others say about PHP. Some of it is true, but sometimes I still feel like someone is critiquing PHP based on what he/she heard about it from someone else who read about it on a blog back in the PHP3 days. When that happens, I sometimes feel compelled to defend the language. Others criticise PHP but because they’re in the same position as I am: they wrote PHP for years, and now have moved on to a better language.
Would I recommend golang to others? Of course! However moving from PHP to golang isn’t as small a step as some might think. It pays of to have an idea of what “thread-safety” means, what people mean when they say “object layou in memory”. Sometimes just understanding how memory is allocated, you can make really simple changes, that result in less allocation calls and less overall memory allocated by changing just a single line. It’s an attention to detail you can’t develop when writing in languages like PHP or Python.
For those who are interested: Here’s a list of plugins I would strongly recommend you set up if you’re thinking about using vim + go as your main development environment.
- Syntastic ( with extra’s)
- Neocomplete (personal preference, YCM might be better for you)
- sebdah/vim-delve (debugging)
- Shougo/vimshell.vim (debugging – Yeah, I’m on vim8, not neovim)
- Shougo/vimproc.vim (debugging)
- vim-fugitive (git integration)