Why I am using Go more
I’ve been subscribed to the Go mailing list for over 10 years. But I never really dived into the language. Work requirements never pushed me in that direction. In hindsight I regret not embracing it more. There are some qualities to it that really appeal to me. Particularly after developing a passion for Typescript and Nim.
A basic example is Go built in linting with the
fmt package. Its a very subtle detail but it has an impact. Requiring all code to conform to a standard prior to compiling.
rubocop to aid code cleanliness. Great tools, but they can lead to debates regarding small details in their configuration. I quite like having an immutable code format. I can hit the ground running without having to configure a linting environment to make the team happy. Deno (a modern Node runtime built with Rust and V8) has also embraced a default formatter. With this strategy every project has a reasonably consistent standard.
Configuring Node to be in a happy place
ts-node 1. Throw into the mix
jest for testing
eslint as previously mentioned for code quality. Then
express to make routing simple perhaps some
@types/lodash etc for every dependency there is usually a corresponding type dependency.
Go has an amazing batteries included standard library testing, linting, basic routing utility is all an
import away. In the simple services I’ve been writing, I found fewer overall packages to install. It could be the nature of the services, but it seems to hint that language is well rounded for the types of tasks it’s used for..
The call for compiled runtimes
After using containers for a while and philosophizing over languages. It dawned on me that one of the features of dynamic languages like PHP was your code wasn’t compiled. That having individual files interpreted at run time was a selling point. It meant for deployment you just FTP the file diff or
fsync (predating CI/CD practices) to your runtime system. Minimizing the time to deployment saving the hassle of a large compile deploy life cycles.
But introduce containers into this equation. The deployment step now involves installing dependancies for PHP (or Ruby, Node, Python) and baking it into an image. This means we’re deploying all the files and dependancies all the time, which is good for reproducibility. But is also very similar to building a binary to distribute.
Why should I use a dynamic language if I deploy everything all the time?
Programming languages like Nim and Go in my opinion are a joy to work with. And if we are embracing containers as a mechanism for deployment why employ a dynamic language. The counter argument would be team familiarity with something like PHP therefore continue writing services in PHP. But I haven’t found Go sufficiently difficult to pick up, the cost to adopt is pretty low.
And compiling to an executable means a container doesn’t need to inherit a base linux version. You can compile in a linux container then copy to an empty layer, avoiding a hefty base image. You can make an image that is effectively the size of your binary. This also avoids N number system utilities that may be introduce a security vulnerability.
Ultimately I find using something like Go builds and tests faster than a PHP or a Ruby equivalent. With a smaller foot print making time to live a lot faster. And with an added bonus of a more scalable runtime, a little bit of a subjective statement, but generally speaking more scalable.
There are many other benefits safety around static typing, safe concurrency. But the real reason I’m using Go is… I like it. And it fits nicely into this C like language preference I’m developing. Typescript Nim and Go are all C like (Von Neumann type languages) and trying to align myself to this spectrum of languages simplifies the scope of languages I was previously pursuing.