Sunday 29 March 2020

Ruby with a Side of Sorbet

I come from a world of types. The languages I know best (C, C++ and Go) are all statically typed languages. Living in the dynamically typed word of Ruby, PHP or Javascript you would think would feel freeing. Instead, I feel annoyed and frustrated at my loss of a security blanket.


PHP

As early as PHP 5.0, types started to slowly creep into the language by way of type-hinting. As of PHP 7, typing is becoming more prevalent and I, for one, applauded it. My first job was working on a Managed Services team whose job was to fix broken sites and we worked in PHP. A vast majority of bugs would have been caught and fixed with typing or proper index checking.

Other developers who had never worked in another language, or only flirted with typed languages in school, didn't understand why I cursed PHP. Dynamic typing was freeing and easy, why would they want to use typing?


At that time, I extolled the virtues of statically typed languages and urged many to at least start using type hinting. I gained many a convert and soon most of the company started to adopt it, certainly for any new software we wrote.

Ruby

When I joined Shopify, I was returned to the dynamically typed world with Ruby. Ruby was like PHP on steroids. Much of what it does worries me greatly but, thankfully, there's a lot of excellent developers at Shopify and most of the code I deal with is pretty well written. We have style guides that forbid, or at least strongly discourage, some of the gnarly things you can do with the language. There's a heavy emphasis on writing good quality tests, a gambit of code review, and a concerted effort to improve anything we do.

That said, some of the same types of bugs I encountered in the PHP world were repeated by developers in the Ruby world. Issues that, once again, proper typing could have caught. However, this time around, I decided not to fight it. I am surrounded by some pretty strong developers and I was willing to continue to learn Ruby to see if proper techniques could further reduce bugs.

To be honest, they can do a pretty good job and I can certainly see why, when you know what you're doing, you can avoid most of the pitfalls of a dynamically typed language.

And yet...

Sorbet

There's a growing number of developers within our core product that have been pushing for the adoption of static type analysis in Ruby. I'll spare any details on history and alternatives; suffice to say, Sorbet is the solution currently being promoted.

The first time I tried it, I hated it. Then, many months later I bumped into one of our core developers during a conference and had lunch with them. During our conversation, I brought up Sorbet and we got into an interesting discussion in which he encouraged me to revisit it.

You see, when I first tried it, I was still a relative novice at Ruby. Sorbet felt foreign and tacked on. Some of the errors it gave were cryptic and, quite frankly, bizarre. I also had made an important mistake. I'd turned on the strictest level of typing.

Ya, don't do that. Not yet, anyway.

This time, I took the recommendation that gradual typing be used, even on a new project. Slowly increase the typing level as you gain stability and see how it goes. At the current maturity of the typing system, I think this is the wise choice.

The best part? It made some recommendations to write better Ruby. Not only that, it caught several bugs that my tests hadn't exposed! It even taught me, and a peer who is a long-time Ruby developer, something that neither of us knew about the language (that the initialize method should be private)!

Conclusion

Use Sorbet! It feels weird, like a new pair of underwear but once you get used to it, you'll be thankful for it!