
Go Is a Shop-Built Jig - geetarista
http://robnapier.net/go-is-a-shop-built-jig
======
metafex
Lack of generics seems to always be _the_ argument against Go. I have been
coding in Go for over a year now nearly every day and it really became an
annoyance only once: CRUD operations in a web-service expecting JSON-objects.
That's literally the only time where the code-duplication was a problem for
me.

Now, not everything else has been all good (mostly minor issues with community
libs), but the one thing that never ceases to amaze me with go is that: You
hammer out a few hundred lines of code, compile, fix those few syntax errors,
compile again and 9 out of 10 times your code just works. The simplicity of
the language is the key. It's a tool that feels right and gets the damn job
done.

~~~
spion
The funny thing is that adding generics will also improve error handling as
you would be able to make that Result<T> generic from Swift and implement
flatMap for it. This would be as good as exceptions, if not better because its
very explicit and can be made compatible with the existing mechanism.

This is why I find it unbelieveable when Go users tell me "I never need
generics". I look at their code and see

    
    
      if err = logit(FrobulatingMessage); err != nil {
          return err
      }
    

repeated over and over again and can't help it but cringe

~~~
metafex
You get used to that pattern ;-)

Also, the "I never need generics" made me smile. Sure, one can get by without
them, but sometimes, as I said above, it would be _really_ nice to have them.

~~~
spion
Getting used to it is not the point. What I find cringe-worthy is that that's
a bewildering amount of noise. It actually makes it harder to figure out what
a specific piece of code does.

Admittedly the error pattern is so common that I can imagine people getting
very much used to it, but thats not the issue here. The problem is indicative
of Go's lack of abstraction power, and its pervasive. There is no difference
between `filter`, `map` and a regular foreach - every piece of code that wants
to do things like that must re-implement the mechanics of creating new slices
and assigning things to members which are accessed using a specific index. So
many details - I can't see the forest from the trees!

I see the same kind of noise in legacy messy projects where a piece of code
works on multiple abstraction levels and its impossible to think about what a
it does without thinking about the mechanics of how it does it.

Given all this I really can't understand how someone can call Go code
beautiful and clean. My gut reaction is "this will cause a mess couple of
years down the line".

The cost of not having generics in Go is really understated, and it saddens me
greatly. With them, Go would be an extremely interesting language. But
apparently, the language designers believe that you (the user) are not to be
trusted with writing sensible abstractions and therefore are forbidden to do
it.

~~~
themartorana
_Getting used to it is not the point. What I find cringe-worthy is that that
's a bewildering amount of noise. It actually makes it harder to figure out
what a specific piece of code does._

I find that so bizarre. That's on a personal level, I'm not throwing stones.

My two favorite languages before Go came along were Objective-C and Python.
Different tools for different problem-sets of course, but Objective-C can
quite easily be called insanely noisy.

Go is obtuse, but I find its readability on par with Python in that there's
one way to do something, and that way is repeated over and over. I don't have
to worry too much about stylistic preferences between programmers, people
trying to get fancy while writing code (or trying to show off). Our server
code serves thousands of requests per second - I need that code to be rock-
solid, not fancy or overtly minimalistic.

You're right, people do get used to the error pattern. I can either handle it,
ignore it, or toss it up the stack, and I get to make an explicit decision
about that every time.

We've been rewriting critical systems code in Go (from mostly Python) and it's
a joy. I am, of course, the (unintended) target audience for Go - a dynamic
language dev looking for speed, concurrency, and compile-time safety, along
with the simplistic beauty of gofmt, goimports, and so on. But I do find it
beautifully simple, if not entirely "beautiful."

Edit: formatting.

~~~
yohanatan
The difference though is that Python is powerful enough to avoid the
repetitive noise even if use of that power isn't the 'Python way'.

------
sat
Seriously, in good faith, I attempted to learn and write a simple web
application in go.

I found it hard coming from a world where IDE support was available in other
languages that do autocompletion and things like that and development just
moves faster. In go, there is some level of support in sublime text, go for
vim etc, but it is not nearly as full featured as say, IntelliJ. Want to learn
about the javadoc - Command + J. Want to refactor code, much easier than in
go. So tooling is a big problem I encountered.

Next in line is lack of reusable data structures. Sure, embedding of structs
is supported, but lets see...what will you do with a person struct (name, age,
gender) that should be part of a employee struct and also the executive
struct. You have 2 options 1) copy paste the person struct fields into each of
the other structs or 2) you have interfaces and implementations of those
interfaces so you can only deal with it through interfaces using embedded
structs. What we really want is a flattened struct (just like inheritance).
Most time people use inheritance not because its the right thing to do for
that piece of functionality, but because it allows easily flattening out a
data structure so you have reuse of a common data structure with common
properties across other data structures. This one killed it for me with go. I
can't reuse. I am not google to have loads of dollars and when I try to make
things work, I need to be able to keep an eye out for bugs that can creep in
with go where re-use is artificial or takes excessive work to get.

All in all, maybe go has its niche, but for a small shop that runs on scanty
resources and needs to build robust and reliable applications, a heavy weight
like Java or .Net is still ruling the roost.

~~~
kasey_junk
That's funny, because I'm also a Go skeptic but your 2 points are literally
exactly the opposite of mine. On the top 2 of the things I like about Go they
are tooling and removed inheritance.

Being able to fire up a fully formed, non-handicapped environment consisting
of only vim and some command line tools is great. I've tried repeatedly on the
JVM to accomplish this and always end up back with bloated IntelliJ and the
vim plugin as my only option.

I would say that in the last 15 years I've used inheritance correctly a
handful of times, embedded structs are nearly always the correct solution to
data structure reuse problems. That Go prioritizes composition over
inheritance for data structure reuse is one of its fundamental value
propositions, that anyone that has used Java extensively thinks otherwise is
baffling to me.

If Go had a longer history I'd probably argue the exact opposite conclusion of
you. If you are a small shop with scanty resources and need to build practical
business solutions Go seems like a great choice. Conversely, if you are able
to afford the best developers and have massive enterprise software needs,
maybe Java or .Net makes more sense.

~~~
sat
>> bloated IntelliJ and the vim plugin as my only option

Bloated it may be but helps me get the job done faster...much faster than I
can do it in vim. I work on a mac with 16 GB RAM and thats sufficient for lots
of processes. Every bit of the way, I have documentation I can lookup right
within as I type, I have autocomplete that always works, I have debugger
support to catch little things I missed, tons of libraries and plugins that
have stabilized over the years...whats not to like? The downsides (and the
reason I looked at go) are both Java and .Net are memory hogs. I needed
something more lighter that would offer the same level of productivity during
development.

~~~
kasey_junk
But that's the beauty of the go tool chain. I have a source browser (godef), a
documentation browser (godoc), a code style formatter (go fmt), code vetting
(vet), unit testing (go test), a linter (golint) etc. and they are all fast
command line programs. This means that it is trivial to setup a vim/command
line environment the way I like.

In my vim setup with simple key strokes, I can go to the source of, see the
type definition of, see the documentation for the call under the cursor. I
have formatting, vetting, and if you want compiling on save of the file (and
it's super fast). I have autocomplete that behaves exactly as I want it to.

I wish there was better ctags support for go, and the go oracle tool is more
prototype than production software, but on the whole I am much happier with my
development chain in go than I've ever been on the JVM or .NET.

------
kristianp
This piece reminded me of "Zen and the Art of Motorcycle Maintenance", with
its talk of the practical qualities of the language through analogy to a shop-
built gig.

------
dkarapetyan
Notice the author would still rather use Swift when he's doing fun stuff. I
get this sentiment and more than once I've wished there were more constraints
in the language to mitigate the damage some kid with a chip on their shoulder
could do but it says something about the psychology of programmers, "I know
personally I'm good enough to do magical, wizardly stuff with all the cool
stuff that Swift gives me but you, well, you need some training wheels so
we're gonna use Go for this project".

I don't know about you but I'd rather work with people that understand the
tools they are using and when it's OK to do fun stuff and when it is important
to exercise restraint and "dumb it down" for the good of the team. Using the
language to solve the problem of uneven programmer ability feels a bit off.
It's something out of 1984. You can't say "great" in Go you can only say
"good++".

~~~
zackbloom
So you're saying you want programming to be hard because that means you get to
work with smarter people? I think what Go is striving for is simplicity, not
elegance. And that change makes the code easier to write and maintain for
everybody involved. At 10AM I might feel like writing Swift, but at 3AM I'm
sure as hell glad I used Go.

Or, less anecdotally, I maintain about twelve services in Go, including web
services, proxies, and an analytics engine, and I have never been woken up in
the middle of the night with a failure. That was certainly not true when I was
writing Python or Javascript. Erlang or Swift might offer comparable
reliability, but it comes at the cost of a lot of complexity.

~~~
MCRed
When things get serious, I think you'll discover that Go provides far less
reliability, and is far more complex. (What's simpler than "it's already
handled for you with OTP and battled tested for 2 decades"? That's a lot more
simple than "you can't do it in this language and you'll end up with a poorly
implemented half version of OTP in Go."

Of course for toy or small services, go is fine. Erlang certainly could use
the "build a binary run it anywhere" distribution model of Go tool.

But reading all these pro-go articles, it strikes me that none of them seem to
be written by people who really understand concurrency.

Believe me, I wish Go was written by people who had understood erlang. There's
a lot to like about it and it has momentum.

~~~
bojo
I'm not sure YouTube or dl.google.com qualify as "toy or small services", nor
the handful of other relatively large businesses building on top of Go
(CloudFlare, Iron.io, etc).

------
bascule
"Go feels under-engineered because it only solves real problems"

This belies a multitude of real problems Go doesn't solve, like generics or
preventing data races

~~~
zackbloom
As he said in the article, neither seem to be problems which come up in
practice. I maintain about twelve Go services running in production, and
neither failure has cost me any significant amount of time.

~~~
the_af
What kills me is that generics (or any other programming language abstraction)
are not problems, but problem-solving tools. Technically speaking, they are
never needed, if your definition of "not needed" is "I can work without them".

You don't need anything beyond assembly language, really.

The thing with most tools and abstractions is that you don't appreciate them
until you use them -- when you _truly_ use them, not merely when you learn
about them. Then you wonder how you ever lived without them. You don't know if
failing to use an abstraction hasn't cost you a significant amount of time
until you've embraced their use.

To me, this is a variant of the Blub paradox at work.

------
ANTSANTS
Props to whoever built this presentation software. With Javascript disabled,
it gracefully degrades to a basic HTML page. Most others leave you with a
single broken slide.

------
threeseed
What is with Go supporters ? I don't understand why if I don't use Go then I
am not solving real world problems and instead building over engineered
monstrosities. Working in the enterprise features like exceptions and generics
makes it easier to ensure consistency across the platform and our 20+
developers.

~~~
tagrun
> What is with Go supporters ? I don't understand why if I don't use Go then I
> am not solving real world problems and instead building over engineered
> monstrosities.

What is with you? The article is talking about _languages_ , not the category
of problems people are trying to solve using those languages. (In principle,
NASA could have written the Mars rover code in brainfuck).

> enterprise features like exceptions and generics

What is an "enterprise feature"? Sounds like a Java-world word though.

I also don't understand how generics and exceptions "ensure consistency across
the platform".

~~~
threeseed
From the article:

"Go feels under-engineered because it only solves real problems" "and so you
build real solutions rather than finding excuses to use your beautiful tools"

The implication from reading the article is that those of us that rely on
those so called exotic features aren't doing so for serious business and
technical reasons. And it seems to be a common thread amongst many Go users.

And generics allow you to reuse existing components much cleaner and
exceptions allow you to handle errors in a consistent way across the system.
You can build error handling classes but often handling errors explicitly
doesn't scale.

~~~
tagrun
> The implication from reading the article is that [...]

The implication _you inferred_ from reading the article is that...

I think there reason is that there a misunderstanding here caused by a
cultural gap. The Practice of Programming is a very good read which I feel
like recommending to every programmer.

> And generics allow you to reuse existing components much cleaner and
> exceptions allow you to handle errors in a consistent way across the system.

Although I don't think "exceptions allow you to handle errors in a consistent
way" (based on my long and still on-going experience with C++), I still don't
see how exceptions and generics " _ensure_ consistency across the platform".

> You can build error handling classes but often handling errors explicitly
> doesn't scale.

You don't build error handling classes in Go.

~~~
pjmlp
> You don't build error handling classes in Go.

That much is true, you compare strings!

~~~
enneff
Or do type assertions.

~~~
pjmlp
Ah ok, that is a better approach.

------
fineline
But you can't deploy your Go to iOS. Or your Swift to Linux.

I'm getting interested in Nimrod (or Nim as I think it's planning to become).
Compiles to native binaries via C, C++ or ObjectiveC. Even compiles to
JavaScript. So it will run on all consumer and server platforms, on
microcontrollers and in browser.

And it has generics, exceptions, macros, inheritance, and (optional, time-
boxed) garbage-collection.

It's a tiny community which hasn't even managed to get a Wikipedia page to
stay up, but I'm barracking for it.

~~~
tagrun
> But you can't deploy your Go to iOS.

And? iOS and Android supports are on their way in case you're not following
recent developments. In case you're interested in writing programs for mobile
devices, there's already a supporting go.mobile repository with (mainly
targeting Android at the moment).

> And it has generics, exceptions, macros, inheritance, and (optional, time-
> boxed) garbage-collection.

Sigh... this "where's my feature!" argument almost always comes up.

It is not reasonable to expect that feature X that is very important to you
has to carry the same weight for other people.

Some people think that it is unthinkable to write programs without feature X.
If you think that way, then Go is probably not a language for you. Note
however that there are many people who do not think that absence of feature X
is a crippling thing, and do enjoy writing programs in Go.

> It's a tiny community [...]

in total contrast with... Nimrod community?

~~~
pjmlp
> OS and Android supports are on their way in case you're not following recent
> developments.

Yes, but it remains to be seen how Go's view on data structures map
Objective-C and Java APIs.

As for Android support, the Android team doesn't seem to care any little bit
about it, given their statements on Google IO.

So you have developers of a Google language trying to target a Google
platform, where the platform owners just want to support Java (NDK is a kind
of stepchild).

~~~
enneff
The rough shape the Go<->Java mapping has already been formed:

[https://godoc.org/code.google.com/p/go.mobile/cmd/gobind](https://godoc.org/code.google.com/p/go.mobile/cmd/gobind)

~~~
pjmlp
Thanks for pointing this out.

Even though I don't like some of Go's decisions, it would be nice to see it on
Android. After all, I created the ticket request on Android Tools.

But the feedback at Google IO from Android's team in this regard was
disappointing.

~~~
mwcampbell
Why do you want to see Go on Android? Yesterday, on the C++14 thread, you told
me about why you gave up Turbo Pascal for C++ when you started programming for
Windows 3.0 because you wanted to use a language officially supported by the
OS vendor. If we apply that logic consistently, it seems to me that it would
be best to just use Java on Android, unless you want to share code between
platforms.

~~~
pjmlp
I agree, but sharing code between platforms is what I do, as I want to target
both Android and Windows Phone on my hobby coding. So the common language
winner to both SDKs is C++.

The ticket was created back when I was still into Go and was wishing for first
level support on Android.

Still I think it would be nice if it would be supported for those that like
the language.

~~~
mwcampbell
Have you looked at RemObjects Elements
([http://www.remobjects.com/elements/](http://www.remobjects.com/elements/))?
With that (commercial) toolchain, you can write in either C# or Oxygene (an
Object Pascal-derived language), and compile to .NET IL, JVM bytecode (and
from there to Dex bytecode for Android), and even native code running atop the
ObjC runtime for iOS and Mac.

~~~
pjmlp
I know then from the time they used to collaborate with Embarcadero. Although
I left Turbo Pascal/Delphi when Windows 3.x was still actual, I kept on
following Borland.

What I am doing are very basic hobby projects, when private life allows for,
which is seldom the case nowadays. You can check some of them with my nick at
GitHub.

If I would be doing a commercial app, I would be buying either Qt or Xamarin,
mainly because they are better known and using Pascal like languages (except
maybe Ada) is no longer relevant on my CV.

------
chvid
Am I the only one who is very confused by these examples?

A function named "frobulate" \- what is frobulate? I dunno. The function
calls: thingsToFrobulate, logit, cleanupOldest, processOld, doNewThing,
cleanup and somehow FrobulatingMessage is set on the way.

Honestly; you can do the most clever functional programming in the world but
if you naming is like this then your code is just going to be bananas.

And BTW: both Swift and Go are missing exceptions; I think those would be very
helpful here.

~~~
sj4nz
frob is a
[https://en.wikipedia.org/wiki/Metasyntactic_variable](https://en.wikipedia.org/wiki/Metasyntactic_variable)
, but not a "common one" which may have led to your confusion.

~~~
chvid
Ok. Maybe I am not getting the joke then. So thingsToFrobulate, logit,
cleanupOldest, processOld, doNewThing, cleanup and FrobulatingMessage are
"metasyntactic variables" too?

~~~
sj4nz
It just comes down to a habit of giving a name to something as an example of
something that isn't meant to map to any problem domain. E.g. when a
manufacturer is in the business of making "widgets," we know they're not
actually making products that are widgets (whatever those are.)

Once you know that the names being used are not considered to be "important",
the other names aren't as important as well, only the syntax. These
metasyntactic variables are useful for avoiding situations like "Who's on
First?" (e.g. [https://www.youtube.com/watch?v=kTcRRaXV-
fg](https://www.youtube.com/watch?v=kTcRRaXV-fg) ) which is humorous to
native-English speakers, but probably incoherent to non-native English
speakers.

------
lukasm
I would switch from python to Go but

\- Type system needs to be improved e.g. generic code

\- Verbosity, duplication of code are painful

\- Lack of functional features

\- Tooling

\- Maturity

~~~
stock_toaster
Tooling? I am not sure about that one. Go tooling is pretty nice. The one area
lacking a bit is, for want of a better word, "package management". However, I
have been using gpm with success, and others are happy with godep.

For me, the biggest pain point is, to be honest, dealing with json. json in Go
is not as fast as you would expect, due to the overhead of runtime reflection.
Parsing "loose/dirty" json is also _painful_. If you cant be sure ahead of
time if a value is `"1"` or `1` (int or string of int), and have to support
both, you are going to have a bad time.

~~~
sagichmal

        > If you cant be sure ahead of time if a value is `"1"` or 
        > `1` (int or string of int)
    

...then your data provider is _broken_ and you need to take it up with them :)

~~~
stock_toaster
Well, these are B2B customers, who are huge companies. We have actually had
customers say they can't even find which servers are running the code, so
could we "pretty please with money on top" just make it work anyway....

Sometimes you actually have to deal with what you get, and can't just "fix the
other end".

