

Why I Don't Want to Learn Go - dwwoelfel
http://arantaday.com/why-i-dont-want-to-learn-go

======
jrockway
Go is designed for large codebases, which is a problem that the author may not
have, and so he may not see the benefits.

One key feature is that the Go compiler itself is the style guide: it
automatically reformats your code to remove style guide violations. This makes
it easy to work on a codebase the size of Google's because everything looks
like it was written by the same person. We try to do the same thing for C++,
Java, and Python, but it doesn't work as well because the process is manual.

Similarly, compilation time and runtime for every component, no matter how
unimportant, is of utmost importance for Google's codebase. It may not matter
how long it takes to run one one-off script, and it may not matter to you how
long it takes to compile, but it does matter at Google because we compile
every project and run every test after every commit. (OK, builds and tests
that are obviously unaffected are skipped. But it's still a lot of code being
built and tested.) So your Python project that takes 5 seconds to run tests
instead of 1 second ends up wasting decades of CPU time throughout its life
time. Same for C++ projects that take many hours to compile. Go tries to be as
expressive as Python and run as fast as Java (and compile faster than anything
else), and this saves lots of time in aggregate. (Remember, when you break
someone's build, the delay between submitting your change and the system
knowing about the breakage can result in a lot of hair-pulling for the
developers on the project you broke. But if we can know the build is broken
before the change is even submitted, then many hours of developer productivity
are saved.)

Anyway, don't take this to mean that you're doing software wrong if you don't
see the value of Go. Google is a special case and just because we have some
problem doesn't mean you should have the same problems. One-man shops should
optimize for individual efficiency instead of aggregate efficiency like Google
does.

~~~
danieldk
_Go is designed for large codebases, which is a problem that the author may
not have, and so he may not see the benefits._

Aren't most serious languages designed for large code bases?

 _(and compile faster than anything else),_

So, why not invest in incremental compilation for an existing language? E.g.
the ECJ compiler for Java has done wonders in terms of immediate feedback
while developing. clang aims to do the same for C code and slowly makes
editors and IDEs more effective.

 _Anyway, don't take this to mean that you're doing software wrong if you
don't see the value of Go._

I fully agree with the author, on the one hand Go does not provide the
performance of C or C++, on the other hand it nearly no useful new
abstractions to manage complexity. Languages such as Haskell, OCaml, F# or
even D provide a better type system and have similar or better performance.

 _Google is a special case_

Out of curiosity: how much is Go used in Google? What percentage of new
projects use Go compared to e.g. Java or C++?

~~~
wisty
SQL isn't, and if it's not a serious language, what is? Perl and PHP are what
the web app layer was originally built on, and they seem to be designed to
maximize developer efficiency for small projects.

Haskell is definitely interesting. If I wanted to build a large system that
was super-performant, I'd look at C, Haskell, and Go. I don't know enough to
make a great decision, but all three look good.

Go has the advantage of being designed for the kind of thing Google does -
massive concurrency. It's also like C, which make it easier to find good
programmers who are confortable with it. Actually, you'd be hard pressed to
find good programmers who are uncomfortable with a language that's nearly C.
I'm not saying Haskell programmers aren't good programmers, but Google
probably doesn't have enough of them, and they'd have to port their existing
code to a completely different base (bad idea).

The original article complains about Go's GC. For a single process
application, this could be murder. I don't think Google uses a single process.

~~~
danieldk
_SQL isn't, and if it's not a serious language, what is? Perl and PHP are what
the web app layer was originally built on, and they seem to be designed to
maximize developer efficiency for small projects._

I intentionally said _most_ , since, obviously there are serious domain-
specific languages. But stating that Go is designed for large code bases,
creates a false dichotomy.

 _Go has the advantage of being designed for the kind of thing Google does -
massive concurrency._

So, claims the C fan since there's GCD, so claims the Erlang/Scala fan since
it has actors, so claims the Haskell fan since it has green threads, STM, and
purity.

Also, is Google interested in massive concurrency or parallelism?

 _It's also like C, which make it easier to find good programmers who are
confortable with it. Actually, you'd be hard pressed to find good programmers
who are uncomfortable with a language that's nearly C._

That's a good point. But as a result it provides only a marginally better type
system, at the cost of performance compared to C. Why not make it a lot better
than C, with the same performance?

~~~
burgerbrain
Calling Perl domain specific? I think those would be considered fighting words
in some places. ;)

~~~
bane
I love a certain subset of Perl with a passion bordering on mania. While I
wouldn't call it domain specific, I _do_ think it's better defined by the
domains it's not well suited for. I wouldn't use Perl for GUI programming for
example.

It's kind of a domain anti-specific.

~~~
__david__
> I wouldn't use Perl for GUI programming for example.

I would. I used the gtk-perl bindings for a project and I thought they were
very well done. Previously I had only used the C bindings and taking the step
to a higher level language (and more importantly, one with closures) was a
_very_ nice step. It was a much better experience than doing Cocoa with
Objective-C, IMO, but that could have also been related to the specific
(smallish) project I was doing.

------
jgrahamc
This is addressed on the Go FAQ:
<http://tip.golang.org/doc/go_faq.html#garbage_collection>

The authors believe that they can make GC a low overhead operation in Go and
they believe that it's essential to take memory management out of the hands of
the programmer to save programmer effort. Lastly, they say that should you
need to you can always work around the GC by doing your own memory management
(linked example).

It feels like they are trying to honor Hoare's "premature optimization is the
root of all evil" by considering non-GC languages to have optimized the wrong
thing.

~~~
heretohelp
Nobody believes GC is a bad idea, it's a canard to suggest otherwise.

It's that it's a contradiction of terms to say that you are offering a
"systems" language but the language in question has non-optional GC.

Go isn't competing with C and C++, it's competing with Java and C#.

~~~
alexchamberlain
I believe GC is a bad idea. Programmers should know what their objects are
doing.

~~~
jlouis
You are severely mistaken about GC then. GC means to a large extent that
programmers should know what their objects are doing. Perhaps even more so
than in a non-GC'ed language.

The inherent problem with GC is when you put it into hands of people without
that knowledge. Then the GC will save them and reclaim their data, whereas it
would otherwise be a space leak and dead program. This means that you will
have programs that work, but they will run slowly. GC-fanatics like me say
that the program has bad _productivity_ since it spends all its time in the
garbage collector.

The advantage of GC though is this: If you know what you are doing, you don't
need to manage memory in about 90% of your program. It is often either good
enough or _way_ faster than doing it yourself. Both in raw performance and in
programmer time. A hint is that most modern parallelizing malloc routines use
garbage collection internally to make them run more concurrently and faster :)

For the last 10%, the solution is the same as in any other language. You
allocate large chunks of memory and then you handle that memory yourself. The
advantage is that you only have to do this for a small part of your program
and that means you can build software much faster.

The only place where GC is provably a bad idea is in hard real time systems.

------
babarock
Unfortunately, as much as I want to agree with it, the article seriously lacks
any credibility. Go claims to present high-level features (namely GC) for low-
level system programming. Obviously, this sounds new and ground-breaking.
Simply dismissing it on account that "GC is unacceptable [for low level
problems]" is nothing short of stating a disbelief: it doesn't prove anything.

If anyone wants to prove any shortcoming, than maybe they should come up with
a more technical analysis, or at least some sort of benchmarking.

~~~
smanek
Do you seriously doubt that the Go GC is significantly worse than the Oracle
JVM GC (by the metrics of pause times and throughput)? I don't think I've ever
heard anyone suggest that it isn't.

My point with this article is simply that, even if Go's GC catches up to the
JVMs (which would be an amazing accomplishment in itself), it would still be
too inefficient for serious systems work. I provided several real-world
examples to that effect.

If you want benchmarks, check out the numbers from moving some of the critical
allocations off heap (and out of the GCs reign) in the Java HBase project:
<http://www.slideshare.net/cloudera/hbase-hug-presentation>

~~~
flogic
In C, don't people just allocate a slab of memory for critical paths too?

~~~
nknight
Sometimes, perhaps, but simple malloc/free are much faster and more
predictable than what you see in GC'd languages, often mitigating the problem.
On top of that, many critical paths can avoid even those by confining their
memory allocation to the stack, something that effectively ceases to exist in
GC'd languages.

~~~
edwardw
> but simple malloc/free are much faster and more predictable than what you
> see in GC'd languages

 _More predictable_ , very likely. _Much faster_ , this is simply not true.
E.g., quotes from an article by Brian Goetz[1]:

    
    
      The common code path for new Object() in HotSpot 1.4.2 and later is
      approximately 10 machine instructions, whereas the best performing
      malloc implementations in C require on average between 60 and 100
      instructions per call. ... "Garbage collection will never be as efficient
      as direct memory management." And, in a way, those statements are right
      -- dynamic memory management is not as fast -- it's often considerably faster.
    

> allocation to the stack, something that effectively ceases to exist in GC'd
> languages.*

Not true, either. With escape analysis, Hotspot JVM can do stack allocation.
The flag of doing escape analysis is actually turned on by default now.

[1]
[http://www.ibm.com/developerworks/java/library/j-jtp09275/in...](http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html)

~~~
nknight
That writeup is certainly interesting, mostly with regard to escape analysis,
but it's entirely untrustworthy with regard to the comparison to malloc.
First, it appears to base its assumptions about malloc implementations on a
paper dating to 1993 (WTF?!), second is that it thinks "instructions" is a
meaningful metric for judging performance.

------
fauigerzigerk
Where Go fits in seems very clear to me. It is a less memory hungry and less
verbose replacement for Java, fit for the age of fine grained parallelism.

Go will never replace C/C++ for embedded systems and operating systems. Go
will never replace JavaScript in the browser. And Go will never replace
Haskell, Lisp, ML, Scheme, etc, for those who have a very deep interest in
programming languages themselves.

------
zoul
As for the GC speed, how do GC and manual memory management compare to the
Automatic Reference Counting system that was introduced recently into
Objective-C? It looks to me as ARC has the advantages of both worlds: it
relieves the programmer from managing memory by hand and has no overhead, as
the decisions are made during compilation. I'm a bit frustrated each time
people talk about GC and manual memory management and act like they were the
only options available.

~~~
stcredzero
Check out iGC. The claim is, by tailoring GC to the ObjC runtime in iOS, you
can beat ARC's performance with GC. (Look at how ObjC allocates heap and use
read/write barriers to reduce the number of roots that have to be traced.)

------
reirob
Thanks for the link! The author expresses exactly my thoughts.

In essence: Go is not a system-level language (GC) and for problems where
performance does not hurt so much there are other alternatives.

To add my personal opinion: I would not consider Go for another reason - I
will not invest in a language that is backed by one company. I did this once
with Java and I will not hurt myself again. Java's start was fantastic but
then came all the business crap like EJBs and tons of frameworks.

------
scanr
Why I have learned go:

The overlap between problems that I'd like to solve with node.js and go is
pretty large and I prefer being able to use a statically typed language with
coroutines and multicore support built in.

The libraries are great for server side programming.

Go optimises for both speed and memory usage. Folk who run benchmarks often
seem to ignore the latter but given how the cloud is priced, optimising for
memory usage can be a big win.

Go's GC is suboptimal at the moment. That said, I suspect that it'll improve
pretty quickly. Go benefits from all those lessons learned during the man
centuries spent building the Java GC.

------
stcredzero
_And before you tell me that the GC isn't that big a deal: it is. Literally
every big project I've worked on in a garbage collected language reserves a
bunch of memory off-heap at startup and uses that for allocations on the
critical path because the GC kills performance._

You could replace occurrences of GC with malloc, switch the language to C, and
it would be just as factual. Basically, what the author is saying is
equivalent to, "Real projects have to optimize." Well, yes. This isn't deep.
It certainly isn't surprising, and it doesn't strike me as a good reason for
not learning a language.

~~~
smanek
It's different, because I'm saying that much system level work has to optimize
by _not using a garbage collector_. I've literally implemented off-heap
malloc()/free() in Java because GC is so untenable.

I argue that makes a language with has a GC that you can't avoid (as far as I
know, it's impossible to allocate an 'object' off-heap in Go) a fairly poor
choice for much system level work.

Which means, if Go is to find a niche, it's got to be at a 'higher-level.' And
that requires competing more directly against Java or Python - a much higher
bar than trying to be better than C.

~~~
minimax
I don't think you're getting his point. I can still replace GC with malloc()
and we end up with the same criticisms of C that you have of Go and Java.

> I'm saying that much system level work has to optimize by not using
> malloc(). I've literally implemented off-heap malloc()/free() in C because
> malloc() is so untenable.

Anyone who has had to write fast C programs that make a lot of small objects
eventually ends up here. You end up incorporating some sort of pool based
allocator, which I'm sure you can come up with in Go just as you can in C (or
Java, or whatever).

~~~
pjscott
You could make the same _kind_ of criticisms, but not with the same strength.
there are real quantitative differences between the speed of explicit
malloc/free and even a really nice garbage collector. (Unless you have a very
special allocation pattern, like a whole lot of short-lived allocations and a
generational garbage collector that uses stop-and-copy for the nursery
generation. That's like the best possible case for GC.)

~~~
stcredzero
1 - a whole lot of OO and functional Lisp programs use your "very special"
pattern of short lived allocations.

2 - You can rig the game so generational GC beats malloc/free.

3 - It's not a criticism, it's a general principle. One always pays for
performance. If your performance requirements are low enough, you can even
take out a loan on them, so to speak, by using a more expressive language.

------
dhconnelly
I understand and recognize as valid all of the author's concerns. I am
personally using Go for things that I used to do in Java. I recognize that
this may not be realistic for people heavily invested in the JVM, but I'm
finding development with Go to be much more enjoyable than Java.

------
breckinloggins
I agree with the GC point. If I'm using a low-level language, my litmus test
is "could I write an OS Kernel in it".

I have a naive question: could GC in Go be replaced with something like
Apple's Automatic Reference Counting (ARC)? It could be an optional feature
backed by inserting real alloc(), retain(), release(), and destroy() calls, so
you'd still have full control if you wanted to turn it off.

------
jbooth
The thing with Go is, it's really easy to write your critical path in C and
then write the other 95% of the code in Go and not have to deal with crap like
null-terminated strings and a lack of built-in data structures.

Go has better integration with C than any other language I've seen.

~~~
pjmlp
Better than C++ and D? You must be joking.

~~~
jbooth
Ok, not better than C++ and I haven't used D. I should've said "other mid-to-
high-level langauge". But using C++ doesn't solve my complaints about the
clunkiness of the non-critical path stuff. Still have wacky string handling
and I'd rather write my own bintree or hashmap than have to use STL.

~~~
pjmlp
And throw away years of experience in optimization from the compiler
developers?

You surely have lots of free time available.

~~~
jbooth
In fact I don't, which was why I said "critical path in C, rest in Go".
Usually I do Java but if I need to use C, I'd like to just write the part that
needs to be fast, then drive it using something else. Python is also
acceptable when it comes to parsing command line options and the like, and
it's as slow as dogshit.

"Lots of free time" would be dicking around with cryptic STL error messages.

------
webjprgm
Why can't someone make a language where you can optionally use GC on one chunk
of memory and use automated reference counting on another chunk? Tell the
compiler which variables should be in which category, and then most of the
quick programming is done in GC while all the stuff that needs to be
performant will be in reference counting but automatically managed so you
shouldn't have to know outside of the one keyword to flag the variable and
occasionally breaking a cycle when you want to free a structure (or using weak
references like Obj-C allows).

~~~
jamesgeck0
I'm not very familiar with it, but doesn't C# or the CLR let you do something
like this with managed and unmanaged code?

------
digamber_kamat
I think a large portion of online life is already ruled by Google. I will
never use Go only because it comes from Google. A mobile with Google's OS, a
Google browser and Google for email and now we will also code in a language
controlled by Google?

I have nothing against Google, but as a community of web developers our
interest lies in diversifying and ensuring that no one gets more powerful than
us.

Also looking at the features of Go itself, it seems to me that the languages
caters to many needs of Google and not many of us may have those needs.

~~~
jff
I don't like giving over my life to Google either, but there's a big
difference between using Gmail for everything and writing programs in Go. Go
is an open source project. You can fork it _right now_ if you want, call it
Not-Evil-Go or whatever, and BAM it's no longer controlled by Google. They can
never make it just up and disappear, the worst they could manage is to do like
Oracle did with OpenSolaris and force the community to fork it.

------
phatbyte
I wonder why aren't they using something like ARC in ObjC instead of GC ?

------
drucken
Article summary: Go is a "better" Java. Why would it claim to be a systems
programming language?

It is a fair point. If anything it illustrates that Google have mis-marketed
the product rather than anything else.

------
zvrba
In light of C++11, I see Go as something rather obsolete. I see absolutely no
reason why I should spend my time on a language that's different just for the
sake of it, instead of studying new features of C++.

------
heretohelp
I concur with the concurrer and the author with my own more 'positive'
addendum:

I just want a cleaned/tarted up C. Something that doesn't make the critical
mistakes of Go and Obj-C (adding runtime overhead), but adds _optional_
compile and runtime semantics that can be very helpful and powerful.

Some ideas:

No GC. This is _NOT_ negotiable. I'm tired of belabouring that point.

Give me something nicer than the current C bitfield syntax.

Bounds-checked arrays...optionally. Make the distinction very obvious in the
code/type-signature.

Higher-order functions, optionally. I don't really want an object system, just
the ability to utilize callbacks in perhaps a nicer way than how function
pointers currently function. I'd actually be happy with a standardized syntax
sugar for function pointers.

Compile-time (only!) duck-typing and polymorphism. This part I think Go got
right, but its sins were too great and the problem it was solving too poorly
defined to make up for this.

Unicode-native from the ground up.

Clean up the string/array/pointer conflation, adopt the semantics of the
bstring library as the default string type for the language, but leave open
the door for 'raw-er' string implementations.

Don't reify language types without enabling people to implement their own data
structures at the nitty-gritty level.

Cross-OS green-threads might be nice. Let people define their own concurrency
models and semantics on top of what the language provides by default though.
Same problem as the language type reification, don't delude yourself into
thinking you've solved the world's problems with your subset of solutions. Let
people use things like ptrheads without punishing them for doing so.

But most profoundly of all:

Make a language that would make writing a library like libev or libevent less
bug-ridden and a lot more fun.

P.S. I sincerely hope someone writes a "pragmatist's" systems language like
this.

~~~
berntb
>>No GC.

Interesting that you disqualify Objective C? It use reference counting which
should have a more predictable memory handling behaviour.

Or is the dynamic stuff too much overhead for you? To me, it looks cheap (but
I'm a scripter since quite a few years).

(Not knowledgeable on this; I'm asking, not making an argument.)

~~~
heretohelp
It seems most people don't really understand the core of systems programming.

Let me try to summarize:

There can be _no_ limitations of any kind in terms of expressing to the
machine, precisely how the machine should behave.

Period. No ifs-ands-or-buts about it.

This means you must be able to define memory layout, management, instruction
behavior and semantics, and optimally, be able to predict cache locality
(arrays vs. linked-lists are the trivial but canonical example)

The moment the programming language, at any fundamental level, precludes me
from defining how the machine should behave with respect to memory, semantics,
or otherwise...it ceases to be a language that can be used for systems
programming.

Disintermediating the meddling of C compilers is hard enough, languages like
Go and Java are 'intractable' to say the least for actual systems programming.

Obj-C is only acceptable in the context of systems programming when you stop
using everything that makes it Obj-C and just write C code.

I outlined additions/improvements that could be made to C _and_ utilized in
the context of systems (rather than applications) programming.

In a single sentence, it's about fundamentally about _POWER_ and not "speed".
That's why the desert-island language is C.

~~~
batista
_It seems most people don't really understand the core of systems programming.
Let me try to summarize: There can be no limitations of any kind in terms of
expressing to the machine, precisely how the machine should behave. Period. No
ifs-ands-or-buts about it._

Actually it seems you don't understand that people mean different thing by
"system's programming".

Not all system programming is about no-compromise, i.e as it would if it was
only about driver or OS coding.

I'd trust Ken Thompson and Rob Pike to understand what system programming is
better than some random dude on HN.

~~~
jacquesm
Chances with these 'random dudes on HN' are that they actually know a thing or
two, I'd hate to make any assumptions there.

As for your 'what people mean by systems programming', how about you both
stick to the definition/description used here:

<http://en.wikipedia.org/wiki/System_programming>

That would make it much easier to communicate. From the looks of it systems
programming is all about no compromise, specifically for the reasons outlined
by the GP. Now I wouldn't know him from Adam but even outside the realm of
driver and OS programming there is plenty of room for software that is 100%
deterministic in terms of time and space consumed.

Note that the 'alternate usage' term in the page linked above was specifically
not what the GP was talking about if I understood it correctly.

~~~
heretohelp
You have it right and seems to understand systems programming and the
consequences of the necessities underlying it perfectly.

------
batista
For all the talk of the speed benefits of Go, and it being static et all, I
don't see much improvement over, say, Python.

A lot of the questions re speed bumps on the mailing list are answered with
"those are microbenchmarks, what matters is real cases" and generally a
"lalala hands in the ears approach", even when it's obvious that the problem
is deeper than some microbenchmark only case.

Like this example:

[https://groups.google.com/forum/?fromgroups#!topic/golang-
nu...](https://groups.google.com/forum/?fromgroups#!topic/golang-
nuts/HDz5KiG6oMY)

[Downvote? Something very controversial about hashmap O behavior?]

~~~
jacquesm
You could compare python with perl or php, you could compare Go with C, C++ or
Java.

But to compare Go to Python is a bit weird.

Of course, you _could_ do it, but why would you, almost every metric that
you'd want to use would be off. You're comparing a compiled language with
lightweight threads aimed at just-above-low-level programming backed by a
single vendor with an interpreted language that is mostly geared towards
single threads of execution with a very high level of expressiveness that is
developed by a bunch of open source gurus under the supervision of a
benevolent dictator.

~~~
dripton
I think it's fine to compare Go and Python. They're both general-purpose
programming languages. When choosing to write a new program, you can often
pick either of them. I can imagine problems where either might be a reasonable
choice. In fact, there are programs that I've written in both. (Granted, those
were Project Euler exercises, not code that someone was paying me to write.)

Don't get too caught up in the marketing.

~~~
jacquesm
> I can imagine problems where either might be a reasonable choice.

Yes, I can imagine that too. But there are also a very large number of
problems where either one is a (much) better fit, and it would seem to me that
that is the majority of problems, not of the 'toy' variety.

The biggest factor in picking a language for a specific project is (in my
opinion) availability of libraries and familiarity with the language by the
team. Python scores very high for a large number of people in both those
categories but it has been around for a while.

Go is backed by one of the largest software companies on the planet so it
stands a chance but google has a bad rep when it comes to cutting off projects
in mid stride.

The devil is always in the details with choices like these and without knowing
more about a specific problem and the people that you intend to do the work
with it is hard to say which one is the better fit beforehand.

------
Roybatty
The title is wrong. It should be "Why I Don't Want to Learn Go and You
Shouldn't Either"

