
Impressions of Go - icey
http://blog.bensigelman.org/post/56158760736/golang-impressions
======
jlarocco
Articles on Go are getting a little boring. The majority are written by people
who've spent an afternoon looking at Go and decide to rehash the same 5 bullet
points. In the time it takes to read their "article" I could learn the same
stuff, better, by reading the official Go tutorial.

Some in depth reviews based on actually using it for an extended period of
time on a large project would be nice...

~~~
zeeboo
The problem is that even those are boring. I've used Go for an extended period
of time on a large project and there's nothing to report. It works just like
what everyone else already says.

~~~
Arnor
That's what's awesome about it! Everybody who uses it gets the same
impressions of it (EDIT: and those impressions are 95% good). What other
language has that going for it?

~~~
Peaker
I think there's a survival-bias/selection-bias here.

Those who tried Go and came from a background of more advanced languages just
threw it away quickly and wrote nothing about Go.

~~~
jzelinskie
I've seen a few Haskellers finding similarities and praising Go[1]. Go is just
meant to be practical and familiar to most working engineers and all the
articles are going to reflect that. Most of the people coming from "advanced
languages" are looking for new paradigms to move forward. When it comes to Go,
there really isn't much to talk about besides the maturation of the toolchain.

[1] [http://www.starling-software.com/en/blog/my-beautiful-
code/2...](http://www.starling-software.com/en/blog/my-beautiful-
code/2009/11/22.the-go-language.html)

~~~
Peaker
The plenty of Haskellers I know have all expressed disinterest in Go as a
poorly designed language.

The linked post seems to be a very superficial take of Go. I wonder if he'd
keep his opinion of Go after learning about lack of generics, error product
types, nulls, mutability of concurrent messages, and all the other show
stopper design mistakes...

~~~
jzelinskie
As an aside, that article says that Haskell can't guarantee Monads to also be
Functors. Is that a language problem or library problem?

~~~
tikhonj
That's purely a library oversight which has become mired in backwards
compatibility (don't track any of that onto my carpet :P).

It would be trivial to specify that all Monads are also Functors by changing
the definition of the Monad class a little bit:

    
    
        class Functor m => Monad m where

------
dvt
This claim: "Python/Ruby/Javascript: my experience is that large systems are
difficult to maintain in these languages, as the dynamic typing makes it
difficult to refactor large codebases without introducing errors in poorly
tested areas of a repository"

\-- is unfounded. Even though there may be some good reasons why one might use
Go instead of C/C++, I find it hard to justify using Go instead of
Python/Ruby/JS/Java (the only criticism of Java - that it's verbose and hard
to tune - is questionable as well). I've said this before. I like Go. I
contributed to Go. I've used Go and I still use it from time to time. But much
like D, I don't think it has a niche.

There are magnitudes more libraries and resources available for
Python/Ruby/JS/Java -- thus far, it's been more than enough to sway me into
using those languages (mostly JS/Java) instead of Go.

~~~
pron
I share the sentiment. People often mention that Go is less verbose than Java
like they were talking about Clojure or something. Go is just a little less
verbose than Java (other than in a hello world example), and targets the same
conceptual "level" (same order of abstractions, same "distance" from the
metal, although Java can get closer to metal than Go). So, sure, it feels a
little more modern in some respects (and less modern in others), but when
considering both languages carefully, I find I really need a magnifying to
tell the two apart. If Go had offered everything that Java does, I still
wouldn't have had a compelling reason to switch because the differences are
just too small.

But Go doesn't offer everything Java does. Like you said, Java's ecosystem
dwarfs Go's. Java has dynamic linking, runtime code instrumentation,
unparalleled tooling, and better performance than Go. The only advantage I see
Go has over Java is a shorter startup time, which makes it a reasonable choice
for writing command-line programs. As for concurrency constructs, Java is far
more flexible than Go, and because goroutines and channels _are_ easy, I've
ported them to Java[1] (and Clojure).

Go sure is easy to get started with, but it would have to be 20 times better
than it is to make me give up the JVM. In reality, it's just a recent,
beginner-friendly Java without the awesomeness of the JVM.

(P.S. I'm not sure Java's often mocked factory-factories aren't simply a
result of the huge number of multi-million LOC programs that have been written
in Java. It's just experience, and Go sure doesn't have the necessary
abstractions to make engineering large systems any easier. Other recent
languages -- sure -- but not Go)

[1] [https://github.com/puniverse/quasar](https://github.com/puniverse/quasar)

~~~
jeremyjh
You have "ported" a green threads implementation for Java? I'd really like to
know more about that.

~~~
pron
I call them fibers. Or lightweight threads. They're like Erlang processes or
goroutines. You can read more about it here:
[http://blog.paralleluniverse.co/post/49445260575/quasar-
puls...](http://blog.paralleluniverse.co/post/49445260575/quasar-pulsar)

The library is very much in active development.

~~~
dvt
You mention Kilim (but perhaps not in a very good light)! Very cool.

To be honest, I was surprised what you could do with Kilim (and the awesome
robustness of the system). Unfortunately, I don't think Kilim has been updated
for ASM 4.0 -- your library looks interesting though, I will certainly take a
look at it.

~~~
pron
I have nothing but admiration for Kilim, and I considered using it, but I
needed something more modular.

------
electrotype
"Java: too verbose, too many FactoryFactories, painful to tune"

Paintful to tune... Maybe. But I don't understand why so many people say
patterns like FactoryFactoryFactories are inherent to Java!

I can write Java code with NO factories at all. Writing shitty and unflexible
code is really easy. When you understand why a factory is used in a particular
piece of code, you start to appreciate it!

It's also very possible to write C++ or Python code with too many
overengineered components.

Also, I like a language to be verbose, I don't think it is an issue. As long
as the code is clear and easy to read... And it's often the case with Java
programs. For my eyes, Java is way more readable than, let's say, Perl, Scala
or Clojure. I couldn't care less about the number of lines required to achieve
the same result!

I'm getting tired of this Java bashing... The only thing that really sucks
about Java is Oracle!

~~~
sarnowski
In fact, since go does not have explicit constructors, it encourages the
factory pattern all over the place. You'll find static factories everywhere in
the go library.

[http://golang.org/doc/effective_go.html#composite_literals](http://golang.org/doc/effective_go.html#composite_literals)

------
rwmj
I thought it was a pretty poor language, obviously written by people who'd
either never heard of functional languages or never "got" the point of them.
More here:

[https://rwmj.wordpress.com/2013/07/03/golang-bindings-for-
li...](https://rwmj.wordpress.com/2013/07/03/golang-bindings-for-
libguestfs/#content)

There's still room out there for the C replacement language. Something with
ML/OCaml-level of expressiveness but with a replaceable garbage collector
might be the sweet spot.

~~~
burntsushi
> No type inference. Because obviously it’s 2013 and I want to write types
> everywhere.

The `:=` does a fair bit for the programmer in cutting back on writing types.
For me, the most needed place for type inference would be for writing
anonymous closures (like what Rust has). In most other places, I am quite
content with writing the types, particularly at the top level.

> Like what’s the point of all the odd rules around := vs =

The former is short-hand for variable declaration with assignment and type
deduction, while the latter is just regular assignment. The primary benefit
here is type deduction, which partially relieves the lack of type inference.

> and what types you can and can’t assign and pass to functions

Huh?

> And why do you have to declare imports, when the compiler could work them
> out for you (it’ll even moan if you import something which is not used!)

The compiler absolutely cannot work them out for you. If you have a package
`github.com/PeepA/wat` and a package `github.com/PeepB/wat`, how will the Go
compiler know which `wat` package to import?

The Go compiler merely moans if an import (or its alias) hasn't been used in
the source file that it was imported in. I like this feature, even if it is a
mild bother while debugging.

> Hello, world is about 8 lines of code. Camel case! Java rang, wants its
> boilerplate back.

It's two lines. [1]

> No breakthrough on error handling.

 _Breakthrough_? I'm not sure what you were expecting, but I think the error
handling is pretty sane and at least far better than error handling
conventions established in C. It could be adjusted if sum types were added to
the language, but that has its own trade offs.

If you desperately want exception-style error handling, then you can use
panic/defer/recover, but it's frowned upon to overuse it.

> The whole design of GOROOT/GOPATH is completely broken. It’s actually worse
> than Java’s broken CLASSPATH crap which is some kind of achievement, I
> guess.

I have the exact opposite opinion. Did you know that you probably shouldn't be
setting `GOROOT`? [2] After Go is installed, you just need to set `GOPATH` and
add `$GOPATH/bin` to your `PATH`. That's it.

> It’s not even enforced error checking, so bad programmers will still be able
> to write bad code.

That is true, but Go's compiler forces you to address errors returned by
functions that also return another value. You either need to explicitly ignore
it or use the variable the error is stored in. (Lest you get an "unused
variable" compiler error.) This doesn't cover all cases---like completely
ignoring the return value(s) of a function---but don't throw the baby out with
the bath water!

[1] -
[http://play.golang.org/p/ihEoJ0yL9I](http://play.golang.org/p/ihEoJ0yL9I)

[2] - [http://dave.cheney.net/2013/06/14/you-dont-need-to-set-
goroo...](http://dave.cheney.net/2013/06/14/you-dont-need-to-set-goroot-
really)

~~~
masklinn
> That is true, but Go's compiler forces you to address errors returned by
> functions that also return another value.

Barely and badly: you can ignore the error and it's _by far_ the simplest
course of action. Contrary to Haskell where it is easier to propagate it, or
Erlang where it is just as easy to turn the error into a fault if you don't
want to handle it.

> don't throw the baby out with the bath water!

There is no baby in that bath water.

~~~
burntsushi
My post was tempered, even and acknowledged the shortcomings fairly. Your
response indicates that you missed that.

~~~
masklinn
No, my response indicates that I do not think your post was "tempered, even
and acknowledged the shortcomings fairly" (and the one I picked is merely the
worst, your hello world is as disingenuous as Java's with all newlines removed
— a single line)

But hey, I guess I'll give you credit where credit is due: you do know Go's
error handling is only an improvement compared to C's, although you still err
in declaring it "far better".

~~~
burntsushi
Because I did not expound upon the intricacies of error checking with sum
types? Responding to inaccuracies about Go does not imply I need to
exhaustively describe all alternatives in order to be even-handed. Namely, I
was responding to the OP's claim that the Go compiler did not "enforce" error
checking. But it certainly does to some extent. I acknowledged that such
enforcement was not exhaustive _and_ that errors could be ignored by the user.
I even acknowledged insidious cases where the return values are never captured
at all.

> (and the one I picked is merely the worst, your hello world is as
> disingenuous as Java's with all newlines removed — a single line)

I ran `gofmt` on that code before sharing it, so it conforms to Go's "One True
Style". More importantly, my "Hello World" is quite readable, unlike a single
line Java "Hello World". This last point in particular addresses the OP's
central point: that Go is just as verbose as Java because of the length of
"Hello World".

~~~
masklinn
> Because I did not expound upon the intricacies of error checking with sum
> types?

No, it's got nothing to do with sum types, Erlang does not use sum types yet
for all the similarity of Go's error handling to Erlang's, Erlang is vastly
superior.

> I acknowledged that such enforcement was not exhaustive and that errors
> could be ignored by the user.

And that's insufficient, errors can almost always be silently ignored by the
user (even in languages with sum types which turn errors into faults, you
should be able to silence the fault). The issue in Go is that _ignoring errors
is the simplest thing you can do_. And not only that, not ignoring them is a
significant step up in complexity and amount of code.

~~~
burntsushi
I'd really appreciate if you stopped quoting me out of context. I never said
sum types were the only alternative. The second sentence of my GP was
"Responding to inaccuracies about Go does not imply I need to _exhaustively
describe all alternatives in order to be even-handed_." I referenced sum types
specifically because it is often what people suggest should have been included
in the language.

> The issue in Go is that ignoring errors is the simplest thing you can do.
> And not only that, not ignoring them is a significant step up in complexity
> and amount of code.

I agree that error handling requires more code, but I disagree that it
increases complexity. _Most_ error handling cases I've ever written are just
passing them up to the caller:

    
    
        if err != nil {
            return nil, err
        }
    

That is not added complexity IMO---particularly since it is an extraordinarily
strong idiom---so I suppose we are at an impasse.

~~~
masklinn
> That is not added complexity IMO---particularly since it is an
> extraordinarily strong idiom---so I suppose we are at an impasse.

Yes, if 10 tokens, 3 lines and a conditional are not added complexity to you,
I suppose we are.

~~~
burntsushi
Not in this case, no.

------
dvirsky
I know it's not a popular view, but being pretty much in love with Go, what I
find most difficult about it is the lack of any real IDE. And by real IDE I
basically mean: a rich editor, stable code completion, jump-to-declaration
etc; and tight debugger integration.

Unless I'm really unaware of an IDE that has all of them, all the IDEs that
support Go fall short:

1\. IntelliJ plugin - excellent editor, a lot of the intellij goodies; but
I've managed to break the code completion, and it's tricky to configure with
respect to GOROOT and GOPATH. and most importantly, no GDB integration
whatsoever.

2\. GoClipse - reasonable (although buggy) debugger integration, very good
code completion, no jump to declaration which is a pain, plus a wonky build
system - the build can fail and you see no message, and the program just runs
from the previous build.

3\. Sublime with GoSublime and SublimeGDB: the build system is buggy, code
completion is great (managed to break that too on complex projects), no jump
to errors, don't remember re jump to source. I had to do a lot of voodoo to
get SublimeGDB to work half decently, and even that was not very robust
because SublimeGDB is buggy on its own.

4\. LiteIDE - has everything in theory, but just feels a bit clunky and hard
to configure. I didn't like it as an editor and haven't spent much time with
it. But it's constantly improving so I hope it will get there some day.

The rest are Windows only so out of the question, less complete/mature than
those 4, or vim with plugins. I don't like vim, I like graphical IDEs, shoot
me. :)

Again, I really really love Go, I hope it will allow me never to write C++
again in my life. This is not a "Go is not ready yet" gripe. It's just what I
find most difficult about it.

~~~
Ziomislaw
vim + a bit of tweaking , ie. completion plugin [1] (probably there is an
emacs mode too - which has all of the above)

[1]: [https://github.com/nsf/gocode](https://github.com/nsf/gocode)

~~~
dvirsky
I tried the recommended vim plugin. it was okay, nowhere near as powerful as
intellij's plugin - and still didn't solve my gdb issue.

------
coldtea
Imagine if the Go team listened all those that want Generics in Go. It would
be more consistent and closer to perfect language.

As it is, it's a PITA 20% of the time.

(Sure, some say they use it and don't feel a need of generics. Most do
however, and it's a constant in every review, even by people using it for core
infrastructure).

~~~
tptacek
What kinds of things have you written in Go, where the language has been a
PITA to you?

~~~
jff
"Well I _would_ write things in Go, but I keep hearing about this generics
thing so I'm just going to complain about it instead"

~~~
coldtea
Yes, because nobody both uses a language AND has a legitimate complain against
it.

Well, I for one have both. As lots of people. And in fact, it's quite common.
Anyone that used a language should be able to tell you several pain points
about it. Except if he is in his idiotic "oh, this is so much better than the
blub that I used to use, it's perfect" stage.

Have you even read TFA? The guy evaluated the language, done a project with
it, and still wants generics.

------
stcredzero
> C++: too much rope, hard to maintain, painful to introduce at a company with
> no prior C++ footprint, _frightens junior devs who no longer absorb relevant
> memory management idioms in school_

So, are we now in an era when there are lots of people in the job market who
couldn't write a doubly-linked list to save their life?

When I was in my 20's, I noted that there were lots of programmers around who
basically treated compilers as "magic" and hadn't the tiniest inkling about
how they worked. Now that I'm in my 40's, I've noted "so what" attitudes in
languages that require manual memory management. (iOS and Objective-C. ARC
goes a long way, but it still doesn't take care of everything for you.)

~~~
tropicalmug
I am one of those programmers: I have no real idea how a compiler goes about
its business, my university does not offer an accessible compiler class (only
for grad students and very irregularly), and I have no idea where to start
besides trying to force my way through the purple dragon book.

What are things I should know about compilers that I probably don't? What is
suggested reading on compilers?

~~~
RogerL
I am not the person you are responding to, but I don't think the point was to
understand how compilers _parse_ code, but to know how the compiler implements
your code in assembly. I.e. knowing things like the difference between the
stack and the heap, how to do a function call in assembly while passing
parameters, how memory actually gets allocated to you from the operating
system, what happens when a page fault occurs, how the compiler lays out data
in memory (this has huge implications in your code as to whether you generate
a ton of cache misses or not). None of that really has much to do with
understanding compilers, but understanding modern microprocessors and assembly
code.

But, of course, you need to pick what makes sense to you. If all you ever do
is write MySQL queries for low performance requirements apps, probably all of
that knowledge will prove of little use to you. But to actually debug
something when it goes all the way to the OS, to deal with hardware, to write
a device driver, you really can't get far without knowing it. If you are
programming in C/C++ or otherwise doing anything performant (3D graphics, CUDA
GPU programming, and the like) you'd better know all that stuff intimately if
you strive to do more than "program by magic" (when something breaks, randomly
change code until it seems to work without you understanding why).

When you know this, you can basically go into any programming assignment and
get it done. Interface this phone to this hardware? Done. Fix this nasty blue
screen crash? Okay, no problem. Modify the linux kernel for some local need?
I'll get right to it! Without it you are kind of restrained to working on top
of the infrastructure that others have built. Not that there is anything wrong
with that - it's your career, and your life, you might as well try to have fun
while doing it.

~~~
stcredzero
_> I am not the person you are responding to, but I don't think the point was
to understand how compilers parse code, but to know how the compiler
implements your code in assembly._

You said it a lot more concisely than I did!

------
bsaul
Best sum up of the language i've ever seen (plus it seems completely coherent
with what i've supposed so far about that language, both pros and cons).

About the "no generic / you have to cast ,recast / the make issue" , could
anyone here with a bit of experience gives an example of what that would look
like in real code ?

~~~
pkulak
You pretty much can't write your own container without significant pain. That
said, with the built in objects you have a map, list, set (map of bools, which
is actually very nice since maps return default types - false - for missing
entries), and concurrent blocking or non-blocking queue (chan). Stacks get a
bit cludgy, but can be done without too much pain. Apart from those, I've
really never had to roll my own collection class. Someday I may, but it is
surely not something you need to do very often.

~~~
tptacek
On the contrary, I found it significantly easier to write a custom container
(a trie in my case) in Golang than in Ruby (which let's stipulate is pin-
compatible with Python). In particular, Golang provides fine-grained control
over memory layout, and is even expressive enough to implement allocators,
both of which are practically impossible in Ruby.

It's true that Golang grants a very useful power to its builtin maps, which
makes it rankle that you have to cast in and out of interface{} to make your
own general-purpose container. But apart from the fact that interface{} is a
stupid name, I don't find it much more painful to write general purpose
containers in Golang than I found it to write templated containers in C++.

~~~
pcwalton
Go does not provide fine-grained control over memory layout when you use
interface{}.

------
rdudekul
Good pros and cons of Go language. There is some information around why Go and
not say C++/Java/Ruby etc. The statement "I see Rails as the emperor with no
clothes on" seems to be made in haste, since Rails is awesome for basic forms
based apps.

~~~
slaxman
I know a lot of friends of mine who have C/C++/PHP background struggle with
rails at the start, primarily because of the magic of convention over
configuration that happens (they aren't used to it). It takes a while to
understand it. But once you understand it, it's a breeze.

Disclaimer: I am a Rails developer. My views are therefore biased.

~~~
Jd
In many ways the problems people have with RoR are the same problems people
have with ORMs. They abstract away a lot of the clutter, but then, just as you
become totally dependent on the abstraction, you find you need something that
you can't get in the abstracted layer.

When this thing is a substantial increase in speed, sometimes you are totally
f __*ed, since to get it you need to toss away a lot of the detritus. For an
ORM you can gradually phase away parts of it, but for a web framework
generally you can 't architect away the box into which your app is placed.

I'm unaware of any RoR that has successfully scaled, except by removing Ruby
(Twitter). Github is probably the largest existing Rails app (at least that I
use), and there are Unicorns aplenty (the new fail whale), or weird caching
issues that seem to arise regularly.

~~~
grey-area
_I 'm unaware of any RoR that has successfully scaled,_

Ruby is slower and more resource intensive than some alternatives, but clearly
it's possible to scale to large numbers of users and developers with RoR:

[http://www.groupon.com](http://www.groupon.com)

[https://www.shopify.com](https://www.shopify.com)

[http://www.yellowpages.com](http://www.yellowpages.com)

That's not to say that choosing an alternative or rewriting a particular
service or website in something simpler/faster/cheaper isn't sometimes a
better option, but I don't think you can claim convincingly that Rails is
impossible to scale.

~~~
PuerkitoBio
Apparently Shopify has quite a bit of Go on the backend. I don't know any
specifics about the rationale, so I can't tell if this means anything WRT
Rails.

~~~
grey-area
I'm sure they all have multiple services running on different tech. Rails is
clearly not the one solution for everything, and any website growing in scale
is going to hit hurdles and end up rewriting some of their logic, whatever the
language/framework used.

------
VeejayRampay
I see it's become trendy to poke fun at Rails and the hurdles it puts on your
way to "scale". Not only have many companies been able to do so using Rails,
but it also completely overshadows the ease it provides to get started in the
initial phase of a project.

That being said, Go really seems like an awesome language, I've dabbled some
and I can't wait to get back to it.

------
fbomb
For me, no templates + no exceptions = DOA.

~~~
jeremiep
Exceptions I can easily live without; Haskell's monads provide a much better
mechanism for error handling (Maybe, Either, IO, etc).

~~~
klibertp
You have generics^2 if you're using Haskell, so it's no wonder they are able
to replace exceptions ;)

------
oakaz
"The standard library is missing x"

What you are looking for is actually a productive community with a good module
manager. This what Golang is missing.

(Golang fans: don't get me wrong, I use and love Go.)

------
st3fan
How is "deploying modern Java applications, which is a minor nightmare IMO"
true?

Dropping a .war file in a directory is hard? Or am I missing something about
'modern' Java apps?

------
mwcampbell
I agree with the point about statically-linked binaries. However, I wish there
were a compile-time facility for including the contents of a file as a read-
only byte array in the binary. Then web application servers with HTML
templates, and even images and other assets, could be truly self-contained.

------
codezero
I agree with most of this post, but I actually found online resources
(especially golang-nuts and various SO pages) to be very helpful with
debugging.

------
lectrick
The more I learn about other langs, the more I appreciate the language design
of Ruby, even though Ruby is slow as shit.

------
bayesianhorse
OH: "Any tips for getting started with Go?" Answer: "Yes, try Python."

------
rubiquity
I'm getting sick of all these Go goroutines... err threads.

~~~
pjmlp
You mean Modula-2 co-routines. :)

