This is a summary of my impressions of experimenting with Ruby and Go.

A while ago I was in the mood for some experiments with new programming languages. Experimenting is almost always beneficial. Even if I study a language I never use, I might be able to learn some new concepts and become an overall better programmer.

I decided to build a command line tool that does some basic text analysis. First, I wrote it in Ruby because I needed to learn some Ruby for a task anyways. Later, I decided to try Go since everyone is talking about it lately.

The following is a summary of my thoughts about those programming environments.

What Ruby taught me

Ruby really feels like a higher level language. It focuses a lot on abstractions and DSLs. This makes it super quick to get certain tasks done. Also, it makes my code look almost like plain English:

describe '#total_words' do
  it 'counts the total words' do
    expect(@stat.total_words).to eq 904061

Even the core language and standard library include so much sugar to work with that I don’t need to write much code since so many algorithms are provided (think map, filter, inject, …). I just need to find the right one.

Sometimes it’s really surprising how abstract the language core is. ARGF, for example, is a stream that reads lines either from STDIN or from a file specified as command line argument:

ARGF.each { |l| stats << l }

The dynamic nature of Ruby allows easy meta programming. Building blocks like the Enumerable class make coding really productive.

Reading this code I understand pretty quickly what it does. But it takes way longer until I also understand how it works under the hood:

def most_used(num = 1)
  @histogram.sort_by { |k, v| v }

I also enjoy it a lot to have an interactive REPL as powerful as Pry. Since I can look up so many things right inside my development environment, I find myself spending way less time searching for API documentation.

What Go taught me

Static typing speeds up the workflow since I see many errors right in the editor. It protects me against silly typo errors. Go’s strictness also, by some extent, enforces cleaner code by not allowing me to declare unused variables and so on.

The default tooling provided by the Go environment is really helpful. I enjoy having golint and gofmt right in my editor. The default testing tools are great too. I would love to have tooling as mature as in Go when working with a dynamic language.

Since I need to declare the types of my data in Go, I need to think more about relations and architecture. By being forced to think about the data first, I separate concerns earlier on.

As an example: By thinking about the data first, I realized I can just collect total and length upfront instead of calculating them later on (as I did in the Ruby version):

type Histogram map[string]int

type Textstat struct {
	total     int
	histogram Histogram
	length    int

Writing Go took me a little longer since I had to implement a lot of functionality provided for me in Ruby. However, for every task it also made me think about what the computer actually does. This way my program ended up doing fewer unnecessary things. It might also be more performant code.

Looking at the one-liner implementation of most_used in Ruby, the Go version is more difficult to understand. However, if you understand the Go version you actually know what the computer is doing:

func (t Textstat) MostUsedWords() []string {
	max := minInt(len(t.histogram), 10)
	words := make([]string, max)
	for i := 0; i < max; i++ {
		words[i] = t.histogram.RemoveMax()
	return words

Another thing I realized when writing Go was that I ended up thinking about every possible error. It might take a little bit more time if you just want to get something working, but the end result feels more robust.

What’s next?

It would be nice to have all of the advantages of both languages in one programming environment. Maybe my next target should be Haskell?

Most of the advantages listed here are actually not platform dependent.

I love to see the web as a programming platform improve in areas like tooling and coding style. In my opinion, Javascript can already compete with the expressiveness of Ruby. The latest efforts enable us to reason about problems in simple and declarative ways.

Now I would love to see a way to bring the safety and robustness of Go to the web. Unfortunately, I’m not really convinced by the solutions out there. Maybe we could achieve the same goals in a dynamic language by advancing our testing technologies? Which other ways can we find?

There are more comments on Hacker News.