
Why I Don't Like Golang (2016) - wheresvic1
https://www.teamten.com/lawrence/writings/why-i-dont-like-go.html
======
sudhirj
While I think most of the points raised are subjective, the overall theme does
make sense to me. Of late my toolbox has become:

Ruby - for problems that are programmer bound - regular web servers / APIs,
CRUD.

Go - for problems that are CPU / Memory bound - fast servers, proxies, APIs
with lots of long I/O waits or high RPS requirements.

Java - for problems that require modelling - logistics systems, data
structures, algorithm heavy or design heavy problems

JS/React - for UI

~~~
zengid
Interesting distinctions. How do you get them to work together? Http and
TCP/IP?

~~~
inlined
When we migrated Parse from Ruby to Go, we started with two parallel efforts:

1\. I built a Go implementation of resque. This let us swap any async process.
Things that needed async tended to benefit from Go's speedup.

2\. We also moved some internal APIs to Go in a sidecar server to help build
up/validate core library implantations before replacing whole endpoints.

------
randomdata
_> It’s difficult to generate Go code automatically._

But, I must say, I do really like that Go makes the AST a first-class citizen
and a core part of the standard library. While not strictly a Go thing, in the
languages I usually find myself programming in you have to rely on third-party
implementations of varying degrees of quality or, even more common from what I
see in the wild, messy string building. Being able to focus on generating the
tree and have the built-in printer generate the code in the format that Go
users expect is a much nicer way to generate code.

~~~
lazyjones
> _I do really like that Go makes the AST a first-class citizen and a core
> part of the standard library._

Seconded. But I wish they would go one step further and make its compilation /
code generation a first-class citizen too, including dynamic loading of
generated code.

~~~
bunderbunder
I wonder if this is really hard to do in a way that works on arbitrary
platforms.

The .NET framework has had it for a while, but it got removed in .NET Core.

------
anonfunction
> The tried and true approach of providing a compare method works great and
> has none of these drawbacks.

[https://play.golang.org/p/JNhlfYoZgCV](https://play.golang.org/p/JNhlfYoZgCV)

~~~
z0r
worth noting the article was published near the end of July 2016 and these
methods were only added in the following month (and packaged as part of a Go
release in October). i'd argue that since it's a retrospective of a few years
of use, it would be fair to include that criticism even if that release had
come shortly before publication

~~~
randomdata
The criticism is fair given the timeframe, but it equally useful to point out
for the readers coming here today how the language has evolved since that
time.

------
markbnj
Wonder why the article isn't attributed? Had to click back to the author's
home page on the site to find out who wrote it. Anyway, I think these are all
good points but the one that really bothers me is no exception handling. Yeah,
it makes a language more complicated to implement, but handling return values
all the way up the stack is cumbersome and error prone. The vast majority of
the time when something goes south deep in the stack I just want to clean up
and send a signal back up to the entry point with whatever information I have.
Having the language runtime handle unwinding the call stack is a big benefit
in these cases. Much simpler to read and write correctly, imo.

------
aaronarduino
It really is striking to me that it is so popular to dislike Go on HN. A lot
of people seem to _have_ to voice their dislike for it instead of just not
using the language.

~~~
bartread
I think it's because there's a relatively large contingent on HN who dislike
Google in general and therefore, by extension, anything they build/support.

EDIT: Why the downvoting? Sure, there are valid issues with golang, but there
are also a small but vocal minority on HN who enjoy being rude to Google
because they don't like Google, which is what my comment relates to. I
certainly don't have any axe to grind with the author, the article, or the
commenter to whom I'm responding. It was just a perspective on why, in
general, golang might get more of a slating than it perhaps deserves, and I
acknowledge that amongst that there will obviously be some people who have
many valid reasons not to like golang. Sheesh.

~~~
stouset
Or maybe it’s because we’ve tried golang repeatedly, been frustrated the
entire way, and are desperately hoping that someone will help us understand
what people actually see in the language.

I work and live in SF. Of people I talk to in real life who’ve used golang for
non-Google, non-toy projects, sentiment is at least 4-to-1 against it, and in
my anecdata that ratio generally increases as people use it for longer.

The one consistent praise I’ve heard that seems genuine (and that I don’t
entirely disagree with) is that it’s easy for a new team member to jump on
board and be productive. Which sounds great, but if this is what you’re
optimizing for at (in my opinion) the expense of nearly everything else, then
it seems like a self-fulfilling prophecy of high turnover.

~~~
matt_m
Sure, I think I can explain some of what people might see in it. Obviously its
strengths/weaknesses will depend on what language you compare it to, the
article mentioned Java so I'll use that.

1) Value types - in Java if you want an array of objects of a non-primitive
type, each one will be individually heap allocated (with some extra per-object
overhead) and stored as an array of pointers (may change in Java 10). Go
allows objects to be linear in memory with no overhead.

2) Slices everywhere - in Go slices are the default list representation. This
allows any API that takes a list of objects to be passed a range of a bigger
list, without copying/allocating.

3) Low-latency garbage collector - I believe Go has one of the lowest latency
garbage collectors in common use (sub-1ms pauses). I realize Java has several
options, but I think Go's is lower _latency_ than all but some
commercial/exotic ones like Zing. This is not saying the GC is better all
around, just on latency. It's also relatively easy to minimize allocations in
Go due to value types.

4) Low-overhead concurrency - lightweight tasks with no blocking/non-blocking
dichotomy in APIs. But threads can scale up a lot, so this might not be a big
benefit depending on the application.

5) Interior pointers - you can lay out structures linearly, and still use
interior pointers. Also, you can use them as interfaces without allocating any
'boxed' objects.

There's probably more, but these are the things that come to mind right now.
Looking back on this list, all of them are performance related. So if an
application isn't performance sensitive in any of these ways I guess it would
be understandable that someone might not see much in it, compared to a
language with a higher learning curve but a lot of conveniences like Kotlin.
Things like capitalization don't seem that big an issue though... maybe
because Go is a simple language the tooling is already pretty good, and you
can easily rename to upper/lower case in an IDE like GoLand.

For people unfamiliar with Go and want to see something more than hello world,
I think an interesting project to look at is
[https://github.com/fogleman/pt](https://github.com/fogleman/pt). It's not
enormous but not trivial either and makes use of interfaces, goroutines etc.
The author's other projects are great too.

------
tschellenbach
While it's not perfect, if you use Dep and VG your vendoring issues are pretty
much solved:
[https://github.com/getstream/vg](https://github.com/getstream/vg)
[https://github.com/golang/dep](https://github.com/golang/dep)

~~~
tetraodonpuffer
I would add retool[1] to the list as it can be useful to vendor your tool
dependencies as well

1] [https://github.com/twitchtv/retool](https://github.com/twitchtv/retool)

------
nickm12
Another article to add to [https://github.com/ksimka/go-is-not-
good](https://github.com/ksimka/go-is-not-good)

------
avshyz
The worst thing about go, it's its dev community. Anyone who claims otherwise
probably hasn't read any of the GitHub discussions (things like this
[https://github.com/golang/lint/issues/65](https://github.com/golang/lint/issues/65)
are pretty common; when users are being told they don't understand how amazing
Go is.)

~~~
skrebbel
I read that entire issue thread and I don't see a single instance of a user
being told they don't understand how amazing Go is.

------
s17n
Implicit interfaces are the single best part of Go. And the “too much magic”
comment is so misguided - author complains it is bad for large codebases but
it’s exactly the opposite. In the real world everyone uses conventions like
those enforced by Go’s so called magic. Having these built into the language
means you don’t have to figure them out every time you look at a different
programmer / team’s code.

~~~
stouset
I repeatedly see this point re: implicit interfaces, and yet it’s never
accompanied by an explanation of its actual benefits.

The one defense I’ve heard is that it allows you to define interfaces that are
implemented by types you don’t control, but this completely ignores the fact
that doing so implicitly isn’t necessary for such a feature, and other
languages (e.g., Rust) elegantly demonstrate why that is.

~~~
bunderbunder
I'd go one further and say that the way other languages do it does a _better_
job of letting you define interfaces for types you don't control. Sometimes
the type you want to apply your interface/trait to doesn't have a function
that does what you need, but could easily be assembled from other members of
the type. And sometimes it does have a function that would work, except that
the name is different.

There's an Uncle Bob talk I watched a while back where he suggests that
oftentimes language designers will say just about anything to avoid admitting
that the real reason a feature is absent or was implemented in a hacky way is
for the convenience of the compiler's authors.

------
andyfleming
2 additional reasons (of my own) which I don't typically see:

1\. No default function parameter values.

2\. You can't require struct fields. So, you can make a new struct, and then
later try to access a field, you get a runtime error (that the compiler didn't
catch).

The second can effectively be solved similarly to the first. If a struct could
take a default value (like a class), then you wouldn't miss something like
creating an empty slice.

~~~
vec
1 is a subset of a smaller issue. Default params are just a way to declare
variadic functions more easily, but the language doesn't allow variadic
functions at all. In go trying to define `add(int x, int y)` and `add(float64
x, float64 y)` is a compile error, even though the compiler can tell full well
which one I want to use where.

2 is so annoying. Half the sdtlib wants you to use `foo.NewStruct()` and the
other half uses `&bar.Struct{}`. As far as I can tell the rule is to use a
bare definition where possible and only declare a New function if the zero
value isn't meaningful. But there's no way for a library author to force the
use of new and/or disable bare struct literals, and there's no way for an API
consumer to know which category a given library will fall into other than by
rote memorization. It's practically designed to invite user error.

Both of these seem emblematic of a bigger problem in the design philosophy of
go. It's optimized for simplicity, but often at the expense of making idiot
proof interfaces difficult or impossible to build. This seems like a
fundamental misunderstanding of what makes programming difficult in the first
place. My package's users (including future me) aren't going to know or care
about how the internals of whatever I'm throwing together work, they just want
to use the API to solve their problem with as little extra contextual
knowledge as possible. Go doesn't let me write an interface where they don't
have to know or care, all in service of a definition of "simplicity" that
doesn't seem to actually make anything easier.

~~~
randomdata
_> It's optimized for simplicity, but often at the expense of making idiot
proof interfaces difficult or impossible to build._

But technically speaking it is optimized for simplicity _of reading code_. The
idea, whether it has worked out in practice or not, was that Google could take
people with limited developer experience and put them into a Go codebase and
have them be able to follow along with the project with minimal introduction
and explanation from already busy teammates.

Your function overloading (Go does support veridic functions!) example is a
good example of where the author and compiler know full-well what the intent
is, but people coming in five years later may not be entire clear on what you
are trying to say. `add` is a simplistic example, but it is easy to see, and I
am sure many of us have experienced, how this can be a problem in more
complicated cases.

As you have pointed out, optimizing for the simplicity of reading has resulted
in increased complexity of implementation. You've only just scratch the
surface of the gotchas in Go. However, that's the tradeoff. Engineering is all
about managing tradeoffs and some will value readability (assuming the theory
that Google has holds – I don't know that anyone has formally measured this)
and others will value writability. Everyone has different goals and is
developing in different environments. There is never going to be a solution
that fits everyone. If there were, we wouldn't need software engineers
anymore.

~~~
vec
I actually find go extremely difficult to read. The abstractions tend to be
both shallow and leaky, the syntax is noisy, and the very limited feature set
forces a particular coding style whether it's appropriate for the problem at
hand or not. It limits expressiveness, which I find makes it harder for an
author to communicate intent.

In other words, go makes it extremely clear _how_ a piece of code works at the
expense of knowing _what_ a piece of code is trying to accomplish and _why_ I
might want to invoke it. I generally think that's a poor tradeoff.

~~~
randomdata
Given Google's penchant for being data-driven, it would be interesting to see
if their assumptions actually play out in the real-world or not. Everyone has
an opinion about programming languages, but rarely does anyone want to look at
it scientifically.

That said, perhaps they have and don't want to admit that Go falls short. But
they've been open about being wrong before when applying the scientific method
and getting unexpected results.

------
sp527
Many of the deficiencies he noted are easily mitigated by tightly integrating
the Go toolchain (and in particular the metalinter) with your development
environment and CD workflow. I highly recommend vim-go for Vim users.

The flat namespacing is rough at times, but you get used to it. It also
encourages you to be judicious in what you make global, which is imo a great
thing. I haven't had a problem with capitalization. It's jarring at first, but
you just get used to it.

There also isn't nearly as much magic as that cherry-picked example might lead
you to believe. Then again, having worked with Ruby/RoR, I've seen just how
gross magical behavior can get _shudders_ and maybe my definition of 'magical'
is a bit more forgiving. I'd like to see a more comprehensive list of such
grievances.

It's possible that the Go ecosystem has improved considerably since the author
wrote this (~1.66 years ago), so I'd love to hear his take on it in the
present day. I do agree entirely about the horrific use of interfaces and lack
of generics. I'll also throw in the lack of enums and poor default error
convention/semantics as additional glaring issues.

This is all made that much more vexing by the fact that Go is so damn close to
being a really great language.

------
andrewprock
Somewhere in my drafts, I have a 101 problems with Go. I only made it to 43,
but I only spent an hour or so on it.

The language they were shooting for feels like "C with garbage collection".
The language they were actually aiming for was probably closer to "something
we can easily transpile python to".

In the end, the language they got is a bit of a mess, with fairly arbitrary
hyper-pedantry causing more problems than it solves.

I still use it, but so far only in the small.

~~~
vec
Go's a great language for Google. Their use case needs very high througput but
can tolerate GC pauses, their code is a giant single-repo monolith with
thousands of contributors where pedantry prevents conflict, and they hire a
bunch of people straight out of college who haven't figured out how not to be
clever yet. "C, but with unremovable training wheels" is a really good
tradeoff for their specific situation.

Why anyone who doesn't share Google's unique issues would want to use it,
though, is beyond me.

~~~
pasabagi
I like it because I genuinely don't have opinions about many of the things Go
is opinionated about.

As I see it, programming is something of a craft, people have different
opinions about how to do it, and the only real way to evaluate these opinions
is to have a lot of experience.

Not having a great deal of experience, I like that Go essentially proscribes a
lot of the stuff people normally have opinions about. It pushes you to write
in a way that, for better or worse, some people think is good. I trust their
understanding of the tradeoffs involved in engineering software better than
mine - and I also trust that, when I outgrow them, I'll notice.

------
baby
> 1\. Go uses capitalization to determine identifier visibility

This complaint sounds like it's more about Go doing it differently than the
language the writer is used to.

> 2\. Structs do not explicitly declare which interfaces they implement.

It sounds like this is probably to have structs that will please several
interfaces, but I can't find a good example of that in the go std lib. Anyone?

> 3\. It’s far too easy to forget to check errors

use a linter that warns you when you do this

> 4\. if I name my source file i_love_linux.go

That's actually a pretty cool and light way to implement something for
multiple platforms I thought...

> If I accidentally name a function init()

Go has so few forbidden keywords that I can't really appreciate this
complaint.

> In Java [...]. Sometimes I find it hard to read Go

So Java is easier to read than Go? Come on!

> I see no good argument for omitting this [ternary] operator

Less ways to write the same thing. Improve code readability.

> Import versioning and vendoring is terrible

I would say Go has the best standard tools. It's not perfect yes, but it's
better than other languages.

> No generics

that's a good thing

This post really feels weird when in another thread of HN's FP you have people
arguing that a 35 LOC package is a good thing in js.

~~~
stouset
I don't mean to be rude, but did you only read the headers and skip the actual
explanations underneath?

~~~
baby
Yes

------
gherlein
Two years old. Could have been titled "I reject the goals of golang" \- many
of the things he hates were actual design objectives of the language. Some are
so minor it's silly. Bottom line is if you don't like it then don't code in
it.

------
vesak
> 7\. There’s no ternary (?:) operator.

I didn't realise there are people who prefer this thing.

Generally speaking, what should we think about languages that are
theoretically weak but are quite successful? Does that imply that the theories
are wrong?

~~~
dingo_bat
Ternary operators are the best! Highly expressive and concise, and everybody
instantly understands it. Is there a single drawback about it?

~~~
citrin_ru
Ternary operators can be abused. E. g. somebody can write code with nested
ternary operator and long expressions. If/else will be more readable in this
case. Go is a nanny language - Go authors give to coders on Go as little
foredoom as possible.

~~~
drdaeman
_Anything_ can be abused. There is no technological or design measure that can
prevent one from writing crappy code in Go or any other language. I'm certain
of this as I had personally written some.

Except for esoteric languages, of course. I've yet to see someone claiming
some code in Malbodge is crappy and offering a refactored version. ;) Just
kidding.

------
simula67
Is no one else annoyed about the GOPATH pedantry ?

~~~
sonaltr
That's one of the first issues I've had with Go. To the point where, all my go
projects are something along the following lines:

projectname:

    
    
      |- go
      |-- src
      |--- domain.com
      |---- username
      |----- projectname
      |------ Actual Code goes here...
      |-- pkg
      |-- bin
    

It's a fun time explaining this to anyone new on the team...

~~~
sethammons
Is that what you are checking into source control? For every project I work
on, the projectname directory is where .git lives. It so happens that when I
'go get', it goes into the whole structure you reference above based on my one
GOPATH that I never, ever change. For those new to Go, you just show them how
it works once. For those used to Go, there are no surprises.

~~~
sonaltr
I'd check the internal folder
(projectname/go/src/domain.com/username/projectname) into source control
(domain.com/username/projectname).

Everyone has a different way they like to setup their environment and I didn't
want to push my ideas onto other users.

~~~
sethammons
I acknowledge that everyone has a different way they like to setup their
environment. If they choose to do it the way that the designers intended, then
they suddenly don't have many of the issues that many folks complain about
around GOPATH and standard build tooling works as expected.

The way you reference is a valid way, but is unorthodox and requires altering
GOPATH for each project. If one is worried about polluting a global space of
packages as they pull in dependencies (the standard objection), that is what
vendoring is for. If someone is not liking all the fuss with altering GOPATHs,
that particular grumbling is easy to fix: don't alter it :)

When I first started with Go, I did the whole "alter the GOPATH for each
project," until I finally gave in. After, things just got simpler. To each
their own.

------
013a
Every day someone publishes their snowflake opinion on why Go is terrible.
Every day, hundreds of highly productive engineering teams write millions of
lines of Go, powering web services and developer tools you use on a daily
basis.

So I'm inclined to side with the engineers actually putting the hours in
instead of the talking mouth bloggers. If there comes a day when Google, or
Uber, or Twitch, or Cloudflare comes out and says "Go was a mistake and we're
starting to replace our old Go code with this new thing", then I'll start
listening.

~~~
crdoconnor
From python to go and back again, by mozilla:

[https://docs.google.com/presentation/d/1LO_WI3N-3p2Wp9PDWyv5...](https://docs.google.com/presentation/d/1LO_WI3N-3p2Wp9PDWyv5B6EGFZ8XTOTNJ7Hd40WOUHo/mobilepresent?pli=1#slide=id.g70b0035b2_1_168)

~~~
013a
There's also a good writeup from Asciinema [1] with a similar theme. These are
valuable articles from people who have clear domain knowledge in their problem
area, which accurately discuss the pros and cons of both approaches.

There's a huge difference between "Go doesn't work for us, here's why, here's
what works" and "I don't like Go". The latter should be a Facebook post and
has no place on HN.

[1] [http://blog.asciinema.org/post/and-now-for-something-
complet...](http://blog.asciinema.org/post/and-now-for-something-completely-
different/)

------
miguelmota
All the things listed are the reasons why I personally LOVE Go. Convention
over configuration.

------
flavio81
I have read many "criticism of Go" articles and this one is one of the most
direct-to-the point.

TL;DR: topics covered:

1\. capitalization rules create inconsistent behavior

2\. Structs do not explicitly declare which interfaces they implement.

3\. No exceptions

4\. A very good one: "Here’s far too much magical behavior. For example, if I
name my source file i_love_linux.go, it won’t get compiled on my Mac. If I
accidentally name a function init() it’ll get run automatically. (...) It’s
fine for small projects but bites you on large ones, and Go was meant to
address the problem of “programming in the large”."

5\. Identifier name clashes

6\. It’s difficult to generate Go code automatically due to the compiler being
picky on imports, etc.

7\. No ternary operator.

8\. (complaint about sort.interface{} that could have been solved using
generics)

9\. "Import versioning and vendoring is terrible. "

10\. No generics.

11\. "The append() function modifies the array in-place when it can, and only
returns a different array if it has no place left. You couldn’t ask for worse
API design. How many bugs are caused by forgetting to assign the result? A
lot, because initial testing may not trigger a resize."

I would personally replace (6) with "absolutely no half-decent metaprogramming
abilities (nor an expressive type system that could give you a workaround
here.)"

~~~
pdpi
The capitalisation issue is the sort of thing you'd tell a junior developer to
avoid in code review: By tying one design decision (what access levels are
possible) to another (code style), they effectively made it impossible to
cleanly change the design around the former, because the latter won't admit
any more values.

~~~
andyfleming
The language design choice to use capitalization instead of a public/private
keywords is, in my opinion, a poor one. It seems like they've made choices to
minimize keywords rather than be explicit and intuitive.

I'm not saying that it can't be learned/taught. Also, IDEs like GoLand help,
but at the end of the day the capitalization approach seems like an
unnecessary annoyance

~~~
s17n
Nope, the point is consistency in large organizations. In other languages,
teams develop naming conventions like these. Having them in the language
reduces the overhead of reading a new codebase.

~~~
andyfleming
There's a difference between consistent code style and forced language
conventions.

Also, I'm not sure you'll be able to convince me that reading "public" and
"private" add meaningful cognitive load to reading code.

~~~
s17n
Right, the difference is that the former isn’t real. When you have millions to
billions of LoC developed by thousands to hundreds of thousands of developers
anything not forced isn’t going to be consistent.

~~~
andyfleming
You can enforce code style through linting and CI. In some projects I've
worked on, code doesn't get merged if it doesn't pass code style checks.

------
dingo_bat
> For example, if I name my source file i_love_linux.go, it won’t get compiled
> on my Mac

What could be the reason for this?

~~~
sudhirj
Go enforces the convention of using the architecture name as the last part of
the filename as a way to compile code specific to that platform. For example,
code that used epoll would be in _linux.go, and the windows and mac versions
would be named appropriately.

~~~
cesarb
That sounds fragile. Does that mean that, whenever golang is ported to a new
platform, code which happened to have the same filename suffix as that new
platform's short name will stop working everywhere else?

~~~
randomdata
Idiomatically, underscores are reserved for files that are given special
treatment, like architecture-specific code or test files. It is not strictly
enforced by the compiler, so theoretically you could cause this scenario, but
if you write Go the Go way, it will not be an issue.

------
myf01d
I tried hard to like Golang but I couldn't. The only good thing about Golang
is that's it's a high level compiled language that's suitable to replace
Python in many use cases especially in the web, there's no other popular
language in this category. However, the lack of features and forcing specific
design patterns for a c-like language is totally annoying.

------
lima
Needs a (2016)

~~~
eropple
Has anything in it changed?

~~~
randomdata
2\. Not a change per-se, but the core team are now often seen using var _
InterfaceType = Struct{} to declare that a type conforms to an interface
(which will also generate a compiler error if it fails to). This seems to
convey the same intent to the reader. Neither solution, as originally noted,
will catch bugs in the implementation.

3\. Tooling will catch when you are not appropriately handling errors,
although I'm a little bit surprised this didn't already exist in 2016. But
I'll assume it didn't. It certainly does now.

6\. Again, not a change, but the patterns to make this a non-issue are perhaps
better understood now. The points are short on intimate details, so it is
difficult to determine if the problem is a result of the author not being
entirely familiar with the language the way that people are today, or if there
is a particular edge case that the rest of us might not consider.

8\. The sort package has addressed this concern.

9\. Go has had a solution for versioning from the very start, so I'm not quite
sure what the parent is referring to. It was indeed a terrible solution for
many organizations, but a lot of work has been done to improve on that. For
all intents and purposes this is no longer an issue.

~~~
parenthephobia
> The sort package has addressed this concern.

How? Looking at the documentation, you still have to write at least three
functions for each type you want to sort.

~~~
randomdata
An example from the docs:

    
    
        sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name })

------
kayall
Has anyone here tried using panic/recover?

I think they are pretty similar to exceptions.

------
jhillyerd
I think this article is a great illustration of the things a Java developer
will struggle with while they are learning Go. I no longer write Java, and I
now view many of these as strengths.

1\. Capitalization rules vary by language, I remember struggling with camel
cased naming in Java in some scenarios. I also thing the example given is bad,
User.user is a poor name in any language.

2\. Structs w/ implicit interfaces. I like this feature of Go, and it's never
bitten me in the way the author describes. I never liked having to declare
them in Java. And there is an easy way to ensure your particular type
implements an interface in Go.

3\. I prefer not having exceptions, and linters will tell you when you are not
checking returned errs. I do wish Go would offer tools to reduce the amount of
if err != nil {} blocks, particularly in IO heavy code.

4\. Go's build system is very easy to understand compared to something like
Makefiles or Maven. I don't consider a few conventions "magic." I have mixed
feelings about init(), but I think it's much better than trying to come up
with thread-safe alternatives to compile regexp, etc.

5\. Naming. Writing unit tests from an outside perspective (package xyz_test)
will help you pick better names, and you will run into less conflicts. In Java
you see hideous combinations of Abstract, Singleton, Factory, etc. I much
prefer Go's concise/pragmatic naming style.

6\. I don't do much code generation, can't comment.

7\. I do miss ternary sometimes, but I have seen it abused with very long
statements in other languages. I would note that "else" has become a code
smell in Go, it's more normal to assign a value and then change it.

8\. Sorting. I like that not everything needs to be an object in Go. Having to
add a few extra lines of code the rare occasion I need to make something
sortable is much better than a project full of Java class/getter/setter boiler
plate for what should have been a struct.

9\. Yes, dependency management is a mess. No argument. Looking forward to dep
becoming official.

10\. I do sometimes miss generics, but I started writing Java before it had
generics so I can live without them :P. I think they can lead to readability
problems when overused.

11\. append is a bit confusing, but hiding how it works should be considered
"magic." linters will help you here.

~~~
parenthephobia
I don't understand your point about sorting. What sort-related Java boiler
plate are you referring to?

~~~
jhillyerd
Boiler plate in my example would be everything that needs to be written for a
class in Java, not specific to sorting: new file, imports, getters, setters
etc. compared to a few lines in an existing file for a struct in Go.

