One month of Go evaluation
I've spent the december with evaluating Googles new programming language Go. The first comments on the language in the net haven't been very positive: nothing new, no clear paradigm, my language (insert your favorite language here) is better due to (insert your favorite feature here). So I'll start with a rant too: the name Go isn't really good. Just try to google it, you get too many misleading links. *smile* So it's very often called or tagged golang. A different name would be better.
The language itself really seems to be nothing new. Since 1996 I mostly used Java, Python, Smalltalk, and Erlang/OTP. And I find many aspects of those languages in Go. So everybody expecting something revolutionary will be disappointed. Instead Google just put many useful features of those languages above - and others - together, useful in the sense of productivity. So I've been really astonished how fast I've been able to reimplement some of my libraries inGo. My favorite features of the language are:
- Even if it is a static typed language it behaves almost like a dynamically typed language. Implicit declarations, no line ending, no braces for the if- and the for-statement, simplified for statement, implicit visibility.
- Garbage collection absolves the developer from memory management, nothing new for many VM languages, but Go produces statically linked binaries.
- The binding of methods to types works like object-orientation without inheritance. Some may interpret this as a lack, but it enforces simple types and the usage of aggregation and composition.
- Like in other languages interfaces allow the definition of a set of methods that has to be defined for own types to work with special functions, e.g. for sorting.
- The empty interface allows variables and arguments with undefined types (type can be determined during runtime).
- A special parameter allows functions with an arbitrary number of arguments, which alows nice, powerful functions.
- Goroutines and channels are a simple and powerful instrument for the creation of concurrent solutions.
- Go contains anonymous functions, that's allways fine.
- Maps as a built-in data type, no extra library needed.
- Easy access to arrays, slices, maps, and channels using the for and range statements.
- The switch statement can work with case expressions, not only values.
- Functions may return multiple values. Naming them already in the declaration simplifies the return.
- Simple and powerful reflection, not only for evaluating but also for the dynamic dispatching of method calls.
- Without reflection a simplified switch based on a type can be made.
- Very fast builds and - after some first benchmarks - very fast execution.
- Rich library for this early state of the language.
- Tools like gofmt, godoc, and gotest - beside others - support the developer, like the well prepared makefiles do.
As said above it's all nothing new, but it's a good combination. Nevertheless there are some disadvantages. I'm missing several features compared to Erlang/OTP, other features are not yet optimal implemented.
- There's no polymorphism. Sometimes it can be simulated using interfaces, but it's not possible to implement the same function or method in the same scope more than once with a different number of arguments or different types.
- Tuples can be simulated with slices of empty interfaces, but that's not really comfortable.
- Together with polymorphism and tuples I'm missing guards, e.g. for separating functions and methods based on values. These are very powerful instruments.
- Go contains no exceptions. Here the multiple return values shall be used, but already the packages of Google show inconsistencies. Smalltalk and Erlang/OTP show how exceptions can be used without contamination of the whole code. Additionally Erlang/OTP shows how both concepts can live side by side.
- Even if the empty interface should enable the code to handle any data the same way the basic types behave different. So no real generic collection libraries are possible. One way could be the enhancement of the empty interface handling, another one the adding of generics. I would like the first one.
- Goroutines can't be monitored, e.g. for restarting them, channel receives can't be done with a timeout, and there's no transparent communication over the network using channels. Here I'm definitely pampered by Erlang/OTP. *smile*
- The handling of maps, arrays, and slices could be easier. If there are len(), cap(), and copy(), why are there no del(), grow(), or contains()?
- A little embedded key/value database for the storage of nested structs in tables would also be nice, together with packages for searching, e.g. via map/reduce. For larger projects I would use CouchDBor RIAK, but smaller ones don't need this.
And now? How to go on? Continue with Go or continue with Erlang/OTP? Or even with both of them? A hard decission. On the one hand I like Erlangs clean model together with the above mentioned features. But on the other hand the productivity I've reached with Go really impressed me. And what's more important, experimenting with clean single paradigm languages or the fast realization of the list of projects that's in my mind in a language which borrowed all its features from other languages? There have been moments I decided to end the evaluation and continue with Erlang/OTP. But each time I found a quick solution, an easy workaround, a different way to handle my tasks. So I think I'll stay a little while longer with Go, realize a small isolated project - I already got one in mind - with it and then write a second blog entry with more results of my Go evaluation.


Comments [0]