Warning: this is a boring “technical” post.
I dug out the source code to Screttler this morning, given that I’ve neglected it substantially over the last few months. For those who are unaware, Screttler is a random password generator with a difference: instead of using dictionary words or random sequences of letters and numbers, Screttler creates nonsense words by chaining vowel and consonant phonemes together, and adding these to numbers and symbols et cetera. Here’s a quick, and rubbish, diagram (please excuse the appalling handwriting):
Screttler is written in Go. Go reached maturity with the release of version 1.0 on Wednesday, so I thought now would be as good a time as any to see how the language had matured, and also to ensure that Screttler worked with it.
The first thing that struck me was how convenient Go has become to use. When I wrote Screttler, each source file had to be compiled and linked manually, á la
gcc. For instance:
This created additional headaches when writing makefiles, because the command for the compiler varied between processor architectures. x86 architectures used
8g; 64-bit architectures used
6g; to produce ARM machine code, you had to run
5g. This was such a hassle that Screttler’s
README file includes the following disclaimer:
(This will only work out-of-the-box on x64 architecture Unixes: if you are using an x86 distribution, you will need to replace every instance of
6lin the makefile with
8l. This is because Go uses different compiler commands for every processor architecture. Similar alterations must be made for ARM, which uses
With Go 1.0, almost all functionality has been brought under the
go command, which is a godsend in terms of convenience. Now, a single source file can be compiled and run with an exceptionally simple:
There are more convenient ways to deal with larger projects, too. It took me less than five minutes to set up a workspace with three directories,
bin, such that an entire package can be installed with:
Aside from obviating the need for makefiles (and good riddance—they’re a nuisance) this actually encouraged me to separate Screttler into two separate packages. The actual password generation engine now lives in its own package,
gentler, whilst the invocation command is now
From an administrative standpoint, this is extremely convenient, and also substantially easier to understand than, for instance, the unholy mess of Ruby’s gem system.
For those unfamiliar with Go, this is what a trivial program looks like:
As you can see, Go looks a lot like C, but with some obvious differences:
- semicolons aren’t required (Go’s compiler automatically determines where one statement ends and the next begins);
- Unicode support is baked in;
- functions are prefixed with the
- the type declaration follows the variable/function identifier, rather than coming before it;
- strings are first-class types.
This ultimately means that Go is familiar, but with a few added conveniences that eliminate many of the traditional “gotchas” many new programmers encounter when learning C. Occasionally, however, I did find myself trying to declare
int x; as opposed to
var x int, and unnecessarily terminating lines with semicolons!
The syntax is streamlined in many places, eliminating unnecessary variations. For instance, all
while loops are now variations on the
The resulting syntax is exceptionally clean. For someone such as myself who has, for educational purposes, been hacking with the abominable hodgepodge of Java for the last six months, coding in Go is a breath of fresh air.
Go supports concurrency, and does it extremely well using something called goroutines. Implementing goroutines is as simple as this:
That’s literally all there is to it. Threading is handled transparently in the background: all you need to do is use
go AnyFunction() and it’ll start chugging away behind the scenes. In many ways, the
go keyword is a lot like the
& on Unix shells, sending the task to the background without any fuss.
Messaging between goroutines is done along channels.
Goroutines also led to an interesting discovery when I was working on beating Screttler into the new package format.
The odd little
Go has a
select statement that I stumbled across when trying to determine where pseudorandom number generation had gone (the
rand package has been deprecated—in its place there are two
rand packages, one under
crypto and the other under
Unlike, for instance, Visual Basic, which just calls its
switch construct a
select statement in Go has a distinct use. To quote the Go Programming Language Specification:
A "select" statement chooses which of a set of possible communicationswill proceed. It looks similar to a "switch" statement but with the cases all referring to communication operations.
Particularly interesting is this property of Go’s
If multiple cases can proceed, a uniform pseudo-random choice is made to decide which single communication will execute.
This turned out to be extremely useful. A lot of the code I’d written in the original Screttler was clunkily declaring hard-coded arrays of phonemes, slicing them, randomly selecting a suitable index, randomly deciding if that was enough syllables, and randomly deciding which type of token (word, number, symbol etc.) to add next.
This was excruciatingly un-idiomatic and fiddly. The use of goroutines and the
select block, however, have made it possible for me to replace a convoluted mess of randomiser functions with a few functions such as this:
This property has made pseudorandom selection in Go highly convenient. I’ve managed to write an entire program dependent on randomness without actually importing a randomiser package at any point.
Of course, this godsend of the
select block will probably have a sting in its tail. I can’t imagine, for instance, that you’d be able to seed the randomiser with some genuinely random data pulled, for instance, from random.org. On the other hand, it meant that I was effectively able to rewrite the entire program in less than eight hours.
This is primarily why I like Go so much. Although, in some places, it’s a little quirky—and frustratingly inconsistent, in areas—on the whole, the process of using Go to write real, functioning code is fun. I haven’t had this much fun programming since when I was originally learning C in 2005, because it feels like I’m actually coding, rather than hacking around the language’s quirks.
I’ll be replacing the existing Screttler GitHub repository with the Go 1.0 compliant version soon.
In the meantime, although it’s not going to be to everyone’s taste, if you’re even remotely interested, I urge you to install the Go toolchain and experiment with the language. It’ll be a breath of fresh air if you’ve been trapped with languages like C++, Java and Python due to work or education commitments.