
Half a decade with Go - geetarista
http://blog.golang.org/5years
======
wwweston
OK, I'll admit it. I've spent six months with Go. I keep waiting for the
moment when I understand it, maybe even develop some enthusiasm for it, and
reach Pike-enlightenment.

And I pretty much hate the language. I feel like I'm writing in something that
combines the worst weaknesses of Pascal and Java. In fact, Mark Dominus'
comments about Java
([http://blog.plover.com/prog/Java.html](http://blog.plover.com/prog/Java.html)
) approximate my experience Go far better than I would have guessed when I
started the project I'm on.

People who seem to be smart nevertheless keep talking it up... some not even
as just a good tool but as their favorite language.

So I'll ask: What is it I need to read/work through in order to at least "get"
Go and really understand its strengths (whether or not I end up liking it)?

~~~
MetaCosm
Composition. That is the single biggest thing that has impressed me as my
codebase has grown. Concurrency and messaging is nice, but I come from
Erlang... I am not easily impressed by concurrency and messaging. Composition,
the power of interfaces in complex systems is the key for me. It is what makes
me stay with Go, and why I will probably stick around for a long time. It is
so obnoxiously useful, without ever getting in my way. Let's talk for a second
about the tiny little function

io.Copy(dst io.Writer, src io.Reader)

It reads data from reader and writes to writer... simple. Now what makes this
little function so darn useful is it takes anything fulfilling its interfaces
(io.Writer and io.Reader). The first way you will probably use it will be to
copy between some stream and a file without having to eat up all the memory to
store the buffer (not using ioutil.ReadAll for example)... but then you
realize you can use a gzip compressor on the writer side, or a network socket,
or your own code... and io.Copy works with anything that fulfills its
interface.

As you build out a complex application, you start by creating your own
functions that take advantage of existing interfaces foo.OCR(dst io.Writer,
src img.Image). After that you start building out your own interfaces... like
a MultiImage interface that has ImageCount and ReadImage methods that returns
the count of images and binary data... but then you realize the images could
be big, so you make the ReadImage method return an io.Reader... and now you
have gone full circle and are using io.Copy to copy imageX from a stack of
images to return to your OCR function that will output the data to an
io.Writer which you made actually a gzip writer because text compresses well.

Beyond composition -- obviously, the concurrency and messaging is nice and
when you need it vital. The other thing that will help make Go "click" is
being very "data oriented" in your design... be vicious and minimal:
[http://youtu.be/rX0ItVEVjHc](http://youtu.be/rX0ItVEVjHc) (great talk on data
oriented design) and be absolutely pragmatic, focus on getting shit done,
always...

~~~
killertypo
I NEED to work Go into one of my projects, but dammit I love Python so much.
it is a warm and safe and comfortable cocoon. :)

~~~
MetaCosm
Then you need to scale and your library isn't actually built in C... or only
runs on 2.x (or 3.x) and the cocoon seals up and you can't escape... you
scream but no one can hear you... you look for help, desperately clawing at
cython, numpy, jython, pypy and C extensions -- they all require you to leave
your cocoon far behind... you struggle and break free... suddenly you are
exposed to the big wide world outside of your cocoon... you look back and
realize the cocoon was just a cleverly disguised prison. /hackernewsstorytime

~~~
killertypo
hahah well I am very comfortable with C and other languages, but I love python
for it's versatility and ease of use! It has some very expressive one liners
that are surprisingly coherent for being one liners.

------
ansible
_At launch, there was a flurry of attention. Google had produced a new
programming language, and everyone was eager to check it out. Some programmers
were turned off by Go 's conservative feature set—at first glance they saw
"nothing to see here"..._

This was totally me. I am very much a programming language aficionado (or
maybe just a dilettante), and when I first read about Go, I dismissed it
quickly. I'd mostly been using Lua at the time, and didn't really understand
what was different with goroutines vs. coroutines.

 _After the initial release, it took us a while to properly communicate the
goals and design ethos behind Go. Rob Pike did so eloquently in his 2012 essay
Go at Google: Language Design in the Service of Software Engineering and more
personally in his blog post Less is exponentially more. Andrew Gerrand 's Code
that grows with grace (slides) and Go for Gophers (slides) give a more in-
depth, technical take on Go's design philosophy._

It was Rob Pike's essay that caused me to investigate it again.

I have been quite impressed with lots of little details that have been 'fixed'
(relative to C) in Go. Such as how variables are declared, the module system,
and much more. And I was and continue to be impressed with the associated
tooling.

I hope that if Go has just one lasting legacy in the history of programming,
it will be how it pushed forward people's expectations of what a good language
ecosystem should provide.

~~~
wyager
What do you think is worthwhile about Go? I agree that the tooling is nice,
but beyond that, there is nothing interesting to me. Goroutines aren't
interesting; languages like Erlang and Haskell got green threads right many
years before Go was on the scene.

~~~
kjksf
You should ponder why Erlang or Haskell achieved a fraction of Go's adoption
despite being on the market 20+ years longer.

Some people see languages as a bag of features (immutability! generic
programming! laziness! operator overloading! algebraic types! hindley-miller
type inference! pattern matching! exceptions! manual memory management!). See
[http://yager.io/programming/go.html](http://yager.io/programming/go.html) for
an example of that line of thinking.

Those people won't get Go.

Designing a language is not about cramming every feature you can think of.
It's about making good trade offs.

A trade off is: you get something but you also loose something.

I use Go because it made the biggest number of good trade offs.

Or to put it differently: I program in Go because when writing code, it
irritates me less than other languages.

If you want a longer explanation of that:
[http://commandcenter.blogspot.com/2012/06/less-is-
exponentia...](http://commandcenter.blogspot.com/2012/06/less-is-
exponentially-more.html)

~~~
wcummings
I get the impression some of the folks in the Golang crowd are "Blub"
programmers [1]. It's not so much a matter of simplicity and trade-offs as it
is a matter of "I don't need things I don't know about", which isn't a good
argument to use Golang.

[1] [http://www.paulgraham.com/avg.html](http://www.paulgraham.com/avg.html)

~~~
timtadh
I feel like you haven't met a lot of Go programmers in that case. The
programmers I have met who use Go or are interested in it are often genuinely
good programmers. Of course there are "crowd" followers in any language as
popular in Go but Go is not a "Blub" language nor does it attract Blub
programmers.

Do I as a Go programmer sometimes wish that Go had feature X. Of course I do!
I want that feature when I want that feature. But, I find Go to occupy an
extremely practical position in my personal programming language continuum do
to its fairly unique mix of features. Note, it is not the features themselves
that are unique many languages individually have them. Indeed, they often also
include features I miss in Go. Rather, it is the particular mixture which is
useful.

EDIT: To respond directly to the Blub article.

Features pg calls out for LISP:

    
    
        Garbage collection, introduced by Lisp in about 1960, is now widely
        considered to be a good thing. Runtime typing, ditto, is growing in
        popularity. Lexical closures, introduced by Lisp in the early 1970s, are
        now, just barely, on the radar screen. Macros, introduced by Lisp in the mid
        1960s, are still terra incognita.
     

Go score card:

    
    
        Garbage Collection [x]
        Runtime Typing [p]*
        Lexical Clusures [x]
        Macros [ ]
    
        * Go has some dynamic typing capabilities but nothing like Python or LISP.
          Many would consider that a "good thing". It partially depends on what you
          are doing.
    

Go has a 3/4 on the score card of features. Macros are of course enormously
useful but also very difficult to shoe horn into a c-family language properly
since they need to be expanded at compile time (unless you just go ahead and
embed you compiler backend into the runtime system of your language. That
would be kinda of crazy/awesome but you could do it). Rust has of course
proven the utility of such a choice.

I can't speak for pg, but Go has many fantastic features and is not a Blub.
The features which are missing are not, by and large, features of LISP.

EDIT 2: To add some more fuel to this fire...

pg concludes the article with:

    
    
        During the years we worked on Viaweb I read a lot of job descriptions. A new
        competitor seemed to emerge out of the woodwork every month or so. The first
        thing I would do, after checking to see if they had a live online demo, was
        look at their job listings. After a couple years of this I could tell which
        companies to worry about and which not to. The more of an IT flavor the job
        descriptions had, the less dangerous the company was. The safest kind were
        the ones that wanted Oracle experience. You never had to worry about those.
        You were also safe if they said they wanted C++ or Java developers. If they
        wanted Perl or Python programmers, that would be a bit frightening-- that's
        starting to sound like a company where the technical side, at least, is run
        by real hackers. If I had ever seen a job posting looking for Lisp hackers,
        I would have been really worried.
    

Note, he explicitly says here: not all languages are the same. He would
__worry __when a company wanted Python programmers. Why? Because to him Python
mixture of features represented a nice chunk of what LISP is providing him.
Let 's do another score card:

Python Score Card

    
    
        Garbage Collection [x]
        Runtime Typing [x]
        Lexical Clusures [x]
        Macros [ ]*
    
        * It is somewhat possible through black magic hackery to create an AST level
          macro in Python. It is messy. It is cool. It's kinda crunky. And I am not
          sure anyone has ever seriously used this ability. It certainly isn't main
          stream. Checkout https://github.com/lihaoyi/macropy for inspiration.
    

Norvig agrees with this assessment: [http://norvig.com/python-
lisp.html](http://norvig.com/python-lisp.html) . Given that many people are ok
with moving from Python to Go
<[https://www.reddit.com/r/golang/comments/2aup1g/why_are_peop...](https://www.reddit.com/r/golang/comments/2aup1g/why_are_people_ditching_python_for_go/>)
it seems reasonable to conclude that Go is an exceptible replacement for
Python. Something no one has concluded about Java (for instance).

Therefore, I believe pg would have been equally worried or almost as concerned
about Go programmers as Python programmers.

~~~
TheHydroImpulse
> Macros are of course enormously useful but also very difficult to shoe horn
> into a c-family language properly since they need to be expanded at compile
> time (unless you just go ahead and embed you compiler backend into the
> runtime system of your language. That would be kinda of crazy/awesome but
> you could do it). Rust has of course proven the utility of such a choice.

Rust doesn't do that. Rust expands the macros at compile-time. Integrating the
whole compiler into the runtime wouldn't make much sense considering what area
Rust is targeting.

It's also recommended to not link a crate that is used during runtime with the
compiler or parser because they're fairly big and would bloat your final build
by a large amount.

~~~
timtadh
yep. I never meant to imply that rust macros were expanded at runtime. I was
trying to use rust as an example of a c-style langauge with a nice macro
system.

------
Animats
Go has a rather specific purpose. It's intended for writing server-side web
systems that will run fast and scale well. Since that's what Google does to
make money, that makes sense. The available libraries reflect this - good
support for dealing with many network connections at once, no GUI support.

It's not suitable for writing an OS, hard real time, highly generic libraries,
or GUI programs. Within its niche, it's far better than the alternative, which
is usually C++. Just the fact that it eliminates buffer overflows without
running slow is enough to justify it.

There are lots of problems with Go. The concurrency isn't safe. The lack of
generics forces overuse of reflection and "interface{}", Go's all-purpose
type. The lack of exceptions forces far too many lines of "if err != nil {
return err}", (or worse, a goto) which takes 3 lines of text every time. The
"defer" mechanism is clunky. Lots of modern bells and whistles, from
functional programming to generators, were omitted. Other than the lack of
safe concurrency, those things don't cause operational problems in your data
center. They just require more typing by the programmers. That's an acceptable
cost. It beats spending time in a debugger.

~~~
ansible
_The lack of exceptions forces far too many lines of "if err != nil { return
err}", (or worse, a goto) which takes 3 lines of text every time._

If I could go back in time, and discuss one thing with the designers, it would
be to fix this.

I'd rather see some kind of Option type (like in Rust) baked deep into the
language. Maybe there would be a scheme where you could use these Option types
as regular values. The moment you try to use one of them that is actually an
error (trying to pass it as an argument to another function without inspecting
it first for example), it causes your current function to return an error.

Or something like that. Maybe that's a language design change that isn't going
to be worked out in a social media post.

 _The "defer" mechanism is clunky._

I like defer. Open a file? Defer close it right afterwards in the code. Bam,
done! That's nice, and works even if there was a panic deeper in the call
stack somewhere.

The idiomatic way to do that in Go, however, can mask errors, like say if
Close() returned an error, you might not see it if you just did a 'defer
foobar.Close()' Those errors should go somewhere... somehow.

~~~
rakoo
> The moment you try to use one of them that is actually an error (trying to
> pass it as an argument to another function without inspecting it first for
> example), it causes your current function to return an error.

I've seen another way to do it, that works with current Go, in a redis client
[1]:

\- Function 1 returns rawarg, error where rawarg can be anything

\- You want to transform arg into some type, so you create a function that
takes a rawarg and an error and returns your type and an error

\- In the implementation of your 2nd function, if err != nil, return it
directly

This way, as a library user you can just chain your calls without the tedious
if err != nil (it will be taken care of in the library).

This might not scale to huge programs, but there certainly is a way to reuse
this idea.

[1]
[https://github.com/garyburd/redigo/blob/master/redis/reply.g...](https://github.com/garyburd/redigo/blob/master/redis/reply.go#L247)

~~~
ansible
I'll have to take a look at that. Thanks for the link.

------
spotman
Crazy that it has been 5 years. Time flies when your having fun.

The golang team has done a fantastic job. It is now my primary language of
choice to get things done.

2 years ago I started playing with it moderately, and now in the past 12
months or so it has made its way into my normal workflow and have been
delivering completed projects in golang.

I am excited for the next chapter in golang. Keep up the good work!

~~~
Kiro
Where do you work where you get to pick so freely? What kind of projects?

~~~
spotman
I am a partner in a software consultancy company. We do any kind of unix based
programming, and have worked on everything from financial software, mobile
applications and streaming video servers.

Most of my work involves building server applications. I have deployed 4
golang apps this year. One is a pre-caching system that concurrently queries a
bunch of mysql servers and caches data into redis. Another is a replication
system from couchdb to postgresql, and the other two are slim restful api
applications that sit in front of elastic search.

------
bketelsen
Shameless promotion in case you don't read OP. We're posting an article every
day on blog.gopheracademy.com celebrating the use of Go around the world.
[http://blog.gopheracademy.com/birthday-bash-2014/go-
turns-5/](http://blog.gopheracademy.com/birthday-bash-2014/go-turns-5/)

~~~
frakturfreund
The RSS feed of this Blog is broken :(

~~~
davecheney
Thanks. Should be fixed now.

------
LBarret
Go is an average language but it's a solid product.

The tooling is excellent. A lot of thougt has been put into making things
simple. From the folder structure to the final binary, everything is smooth.

It's just a shame that the language design itself is quite behind the times.
Older languages had a lot to offer to a new one. The day it launched it was
already old. And I don't see a lot of goodwill to change the language to fill
the glaring omissions.

Python in this respect is quite an example : iterators, generators, ABC were
carefully added without making any less approachable. It prooves it is
possible, but that the kind of things the Go leaders apparently simply don't
consider.

------
codemac
You still need a Makefile if you use things like godep, or their new `go
generate` stuff.

They have a long way to go on tooling; however, getting to say that is a
luxury, due to just how "right" golang has been for systems work. Golang has
been amazing to work with, and has just been stupidly productive. I miss
debugging (gdb) and generic compile tools like tup, but that's about it!

~~~
diyorgasms
Do people prefer not using Makefiles? I ask because Makefiles are a standard
part of my workflow, and while I know I can 'go build' or 'go [whatever]' I
still cling to my Makefiles as a preferred tool.

~~~
dilap
I like make, and get a kick out of possible interesting successors, like tup
and redo. I forced myself to stick to "go build" when starting out with go,
and I'm glad I did...more time working on what I'm working on, less time
fiddling with the build system. I'd recommend it, at least until you really
hit its limitations.

------
dvt
Very awesome. I'm so proud to have been an early committer! Unfortunately, I
don't use Go that much day-to-day, but here's hoping for another 5 years!

------
xkarga00
Does anyone know how Go is used inside Microsoft, except their participation
in the Kubernetes project?

~~~
jhawk28
I expect that Microsoft will be using Go for their Docker integration.

------
ExpiredLink
Why are language discussions so futile? Because people choose platforms, not
languages. Platforms have one main language (in some cases two) which becomes
the language of (no) choice for the developers.

Platform examples: Host (Cobol, PL/1), Unix (C), Embedded (C), classic Windows
(C++, VB), .NET (C#, VB.NET), Java EE (Java), Android (Java), ... Rails
(Ruby), PHP (PHP), Browser (JavaScript).

The choice is always between platforms, not between languages. Languages
without linking to a platform (Go, Python, Scala, D, Rust, ...) have little
chance to succeed.

~~~
EdiX
I don't see how PHP is a platform like the other platforms you mention. Also
Python is very successful, Perl is very successful, Debian was very successful
in its time. Your argument does not seem to be corroborated by facts.

------
jvehent
Writing in Go has made me find Python code ugly. Much like Python made me
dislike Perl many years ago. That is, of course, very subjective.

------
austinz
Sometimes I wonder: if Apple's new language had been Go, and Google's new
language had been Swift, how would reaction by developers and adoption have
differed? (You can also run this thought exercise with Go and Rust, if you
prefer a different competition between self-proclaimed systems languages.)

~~~
kxo
I'm not totally sure how a non-optionally garbage-collected language with a
runtime could ever be called a "systems language."

~~~
_ak
The "systems" in the term "systems language" the Go team used shortly after
initially releasing Go refers to systems like Google has them running.

------
johncoltrane
Half a decade sounds better than 5 years.

------
zerr
How I wish Gilad Bracha was in Go team instead of that js replacement language
nobody is using...

------
callesgg
I would really like to see go binaries that is not like a 1mb in size.

In practice is not like I don't have space for 1MB

But I still want proper linking to a shared "golib"

~~~
jamescun
Binary sizes are a concern, particularly with a move to mobile devices and
later embedded systems.

However for Go's current platforms, I would call it a non-issue. Static
builds, something seemingly long forgotten though supported in other compiled
languages, make deployment and distribution that bit easier.

I would support static builds by default, optional dynamic builds.

------
general_failure
I really dislike the syntax. The language itself has nice concepts.

~~~
dsymonds
What precisely is it about Go's syntax that you dislike?

------
Dewie
> , we were calling Go a "systems language"

And maybe in another 5 years, people will stop bickering over whether that
description is/was appropriate. :)

~~~
agox
Dare to dream big!

------
eng_monkey
A full lustrum.

