
What Golang Is and Is Not - elrodeo
http://danmux.com/posts/what_golang_isnt/
======
codygman
As someone who writes Go every day for work, I can't agree that Go is simple.
Using a language for analytics without generics can be quite painful and error
prone.

Go is a language that pushes remembering corner cases and failure conditions
onto the programmer rather than the language and runtime itself.

When you already have to remember a myriad of corner cases for business logic,
also remembering so many corner cases for your code hurts productivity.

I also believe that languages exist to make getting to an end result in given
domains easier. Go does not make my life easier.

I really hope it gets generics. I wish it would do away with nil/null.

Nim is a very good language that actually accomplishes the simplicity Go
wanted imo.

Go affords simplicity to the Go compiler writers at the cost of burdening Go
users with having to remember inane things.

~~~
divan
> Go is a language that pushes remembering corner cases and failure conditions
> onto the programmer

Can you elaborate on this? I write go for 3+ years and I have no idea what
corner cases and failure conditions do you mean.

~~~
patio11
A corner case about Go which makes me absolutely crazy: calling Reset() on a
timer which has already fired has the biggest gap between "What I expect to
happen" and "What actually happens" of any stdlib I've ever worked with.

[https://gist.github.com/patio11/bc883d566778c323742432c203e6...](https://gist.github.com/patio11/bc883d566778c323742432c203e69541)

(You can see it here in the playground, but try it on your local machine if
you don't believe me and/or think the playground has an inconsistent
understanding of what time actually means:
[https://play.golang.org/p/ltdV9dI609](https://play.golang.org/p/ltdV9dI609) )

~~~
anant
You never drained the longTimer channel, so when you say "We agree that
longTimer has fired, right?"; that's not quite true. After you call Reset(),
you're still getting the value from the first firing, because that's the first
time you read from the channel at all.

The docs are quite clear on this behavior and say "Timer will send the current
time on its channel after at least duration d." \-- key words being _at least_
and says nothing about when you choose to read from the channel.

~~~
kevhito
It's even worse. The longTimer _has_ fired, and it sent a message on the
channel just as it was supposed to. When Reset() is called, it causes a second
firing and a second message. Here is the code, corrected to illustrate. The
output times are exactly as one would expect.

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

------
jksmith
What we like to keep missing is that golang innovates not as a language, but
as a tool to contribute to software project success.

Project success in the software industry is abysmal, and we still keep
thinking we can spin up another language that will contribute to project
success because it let's us express ourselves in new ways. Well, how's that
working out so far?

The reason why golang appears to have such wide adoption in such a short
period of time is that it really does seem to contribute to helping devs get
their shit done. Massive amounts of working code are being written in golang,
and that's good for the software industry as a whole.

Currently I run a massive project written in the standard issue kitchen sink
corporate language (C#). It's got generics, functional extensions, all kinds
of shit to make the most discriminating programmer happy. Well guess what, IMO
C# for all it's features still doesn't serve the business of software dev as
well as golang because it doesn't pull off what golang is brilliant at (easy
to code for wide range of skill levels, easy to mentor, easy to test, easy to
hire for). The result is difficulty finding productive devs, and a code base
that is not up to my preferred quality standards.

This may be hard to swallow, but it might really be the case that you can get
more quality work done with more devs if toolchain simplicity is emphasized
over language features. If the evidence continues to bear this out for golang,
then it's time for me to shed some language biases just so I can remain
competitive.

~~~
xiaoma
Go has been around nearly a decade with the backing of none less than Google
and yet it remains a fairly fringe language. Elixir is on a _much_ steeper
adoption curve. So is Swift, but Elixir doesn't even have a tech heavyweight
behind it.

~~~
geodel
Go 1.0 is released in March 2012 so it is not even half decade old.

~~~
icedchai
You know Go existed before 1.0, right?

~~~
mappu
The question was about adoption curves, and i think version number is a
signalling factor in adoption.

Pre-1.0 version number would certainly hamper adoption in my $DAYJOB.

------
bad_user
As some people like to point out, I'd also like to remind that in 1968 Algol
had:

    
    
        - user defined record types
        - user defined sum types
        - switch/case statement with support for sum types
        - unified syntax for value and reference types
        - closures with lexical scoping
        - parallelism support
        - multi-pass compilation
    

Given that many mainstream languages don't offer even what Algo68 had, I
personally understand how a Go developer might thing that "nothing is new
under the sun" since the 80's. After all, Go ignores all progress in
programming languages for the last 40 years.

I recommend watching "Growing a Language", a legendary presentation by Guy
Steele:
[https://www.youtube.com/watch?v=_ahvzDzKdB0](https://www.youtube.com/watch?v=_ahvzDzKdB0)

I do love the attempts of Go developers to rationalize Go's choices. But in
the end it will end up being a hated language, universally recognized as a net
negative in the industry. But that won't stop the working programmer from
doing the same mistake again and again.

~~~
mixedCase
>After all, Go ignores all progress in programming languages for the last 40
years.

I've seen this meme being spouted so much every time Go's mentioned it's
ridiculous.

No, piling up feature upon feature is not _progress_ otherwise we wouldn't be
using anything but C++.

Go is a language you pick for the right situation. If it's not enough for what
you're trying to do, go for a different one instead of trying to expand in the
wrong direction leaving you with warts, like Java's done, C++'s done, Python,
JavaScript etc... which you will have to end up avoiding in order to write
performant and clear code, counting on luck not to have to deal with code that
abuses those features to create anti-pattern upon anti-pattern.

~~~
AdieuToLogic

      >After all, Go ignores all progress in programming
      languages for the last 40 years.
    
      I've seen this meme being spouted so much every
      time Go's mentioned it's ridiculous.
    

Is it a meme when it is true? To support this question, witness the statements
of Rob Pike[0] below.

\---

Regarding the utility of supporting first-order functions[1]:

    
    
      I wanted to see how hard it was to implement this sort
      of thing in Go, with as nice an API as I could manage.
      It wasn't hard.
    
      Having written it a couple of years ago, I haven't had
      occasion to use it once. Instead, I just use "for" loops.
    
      You shouldn't use it either.
     

\---

Regarding progress in programming languages[2]:

    
    
      One thing that is conspicuously absent is of course
      a type hierarchy. Allow me to be rude about that for
      a minute.
    

And[2]:

    
    
      Programmers who come to Go from C++ and Java miss
      the idea of programming with types, particularly
      inheritance and subclassing and all that. Perhaps
      I'm a philistine about types but I've never found
      that model particularly expressive.
    

\---

The part about "particularly inheritance and subclassing and all that" is
ironically a meme spouted by Go's community so much it is, if you'll pardon my
borrowing your description, ridiculous. For the curious, there are many
community "Go-isms" explainable by the Pike talk[2].

Even a casual reading of the "list of significant simplifications in Go"[1]
(35 in all) is enough to reasonably support the "ignoring all progress"
position.

Of course, YMMV.

0 -
[https://en.wikipedia.org/wiki/Go_(programming_language)](https://en.wikipedia.org/wiki/Go_\(programming_language\))

1 - [https://github.com/robpike/filter](https://github.com/robpike/filter)

2 - [https://commandcenter.blogspot.com/2012/06/less-is-
exponenti...](https://commandcenter.blogspot.com/2012/06/less-is-
exponentially-more.html)

~~~
mixedCase
> [1]:

I don't see how that helps your argument. For loops are more than enough for
that task, it's easily readable and universal.

And Go does support first-class and higher order functions so not sure what
you're talking about here.

> [2]:

How's ditching inheritance in favor of composition "ignoring the last 40
years"? It's the biggest example together with goroutines that proves that
phrase is a meme, and that we've learnt a lot on typing best practices as an
industry over the past couple decades.

And as an added bonus, another thing that's a good example of Go actually
looking back and improving upon what's been done before is the select
statement. Most popular languages fall through by default with the switch
statement.

Outside of examples on the internet, I can't recall right now the last time
I've seen a switch statement in the wild that didn't break at the end of every
case. Making the case (pun not intended) for a fallthrough statement and
having switch/select break by default.

------
sergiotapia
The author is quite correct. Go is super boring, and runs fast. Two great
points for it.

For me however I just never felt happy writing Go code. I have a couple of
open source projects with it, so I have put it through it's initial paces to
see if we fit.

The language that did make me happy was Elixir. Everything about the language
and the surrounding tooling is polished. You end up with significantly less
lines of code that's easy to understand.

Here's just one example from me - both examples scrape some info from HTML:

Elixir:
[https://github.com/sergiotapia/magnetissimo/blob/master/lib/...](https://github.com/sergiotapia/magnetissimo/blob/master/lib/parsers/demonoid.ex#L36)

Go:
[https://github.com/sergiotapia/gophers/blob/master/scrape.go...](https://github.com/sergiotapia/gophers/blob/master/scrape.go#L39)

You tell me which one is nicer to look at and easier to understand.

~~~
leighmcculloch
+100 Go is super boring and that it's a selling point. Code is a tool, not a
device for entertainment. I'm yet to meet a 20+year developer who is wowed by
extensive/unique/complex features, which makes me think as I also mature as a
developer I'm going to find those things less important.

However, the Go version is way easier to understand. Mind you, I have very
little experience with Elixir. In the interest of being pragmatic, the easier
code is to understand, the easier it will be to maintain, and we spend much
more time maintaining code than writing it fresh.

~~~
sheepmullet
> Go is super boring and that it's a selling point. Code is a tool, not a
> device for entertainment.

It is a balancing act.

As an industry we don't "do" training on work time.

So how do you convince developers to work on learning and development during
their own time?

One way is to make the language fun and interesting.

> I'm yet to meet a 20+year developer who is wowed by extensive/unique/complex
> features

20+ year devs don't like jumping onto the latest unproven technique/language.
Don't mistake that for wanting few/limited features in a language.

20+year developers arent driving transitions to go. It is fairly new
developers wanting to switch because it's cool, it's new, and it helps level
the playing field by bringing experienced developers down a peg or two.

------
junke
So, Go is designed to be an engineering language and not an academic toy.
Contrary to other languages, Go programmers "deliver" and have a pragmatic
view of the _real_ development world, not just their own commits. Go
programmers need a deeper understanding of computer science because other
programmers are lazy and have everything given for free and probably don't
need to know how it works.

A whole page discussing the virtues of Go by insulting people.

~~~
codygman
Go doesn't make real world programming easier. It makes you work hard for
pointless things. Most of its problems are from a lack of generics.

~~~
IshKebab
It may be harder to _write_ some things, but it definitely is easier to _read_
Go code.

Besides, while the language itself may be more verbose than it could be, the
standard library is extremely pragmatic and terse. It's like the opposite of
the standard C++ library. E.g. to see if a string starts with another string
in C++:

    
    
        std::mismatch(prefix.begin(), prefix.end(), toCheck.begin()).first == prefix.end()
    

In Go:

    
    
        strings.HasPrefix(toCheck, prefix)
    

The Go standard library is _full_ of things that do exactly what you want them
to, whereas in other languages you have to manually do it yourself.

~~~
clappski
In your C++ example you're giving `std::mismatch`, which is a generic
algorithm. If you're so inclined you could provide a wrapper that has the same
interface as the Go example, but you're comparing apples to oranges. I'd argue
that `std::mismatch` is much _more_ pragmatic than the Go example, in that I
can use it to check any lists of user defined types.

In reality, these two methods do completely different things. `std::mismatch`
is a completely generic algorithm that 'returns the first mismatching pair of
elements from two ranges', which can be used for much more than
`strings.HasPrefix`.

~~~
reality_czech
Did you read the article? The fact that there is 1 way to do it in Go, and 100
different ways to do it in C++ (or some other older language) is a feature,
not a bug.

~~~
gravypod
Where are the 99 other ways? I see one way to do this for any set of data
types. Golang is the one with 100 implementations.

------
tux1968
The article mentions a keynote speech by Rob Pike* from 2012 which is quite
illuminating. The trade-offs made were all centered around google-scale and
the pain points of such a massive operation. It stands to reason that people
working outside of that environment may be less pleased with the language.

[*] [https://www.infoq.com/presentations/Go-
Google](https://www.infoq.com/presentations/Go-Google)

~~~
20yrs_no_equity
Google is not the only entity that operates at scale, and simply because
google does it does not mean it is the correct choice. That's kinda cargo
cultish.

In distributed systems, go is fragile and dangerous -- because it will panic.
IT has no supervision system, and it has the potential for deadlocks, in fact,
unless you engineer around it, all coroutines and channels will produce
deadlocks and can silently kill your program. When that happens you have no
idea why things are broken-- nothings happening.

And this is a language without a decent debugger!

~~~
lossolo
> In distributed systems, go is fragile and dangerous -- because it will
> panic.

Do you know when it will panic? Do you know you can recover from panic if you
for example want to communicate with other systems that this node is going
offline?

> it has the potential for deadlocks

I could write that for most of languages that have mutexes. This is design
problem, not language problem.

> When that happens you have no idea why things are broken-- nothings
> happening.

It's only true if you do not know how to use debugger and don't know how
language features you use works.

------
p0nce
> To provide any solution in Go that needs a dynamic data structure you can
> choose between hand rolled linked structures or a Slice or Map (or compose
> with them). As they are quite different the choice is normally obvious.
> Contrast this to the choice between map, set, hashset, bag etc etc, or
> rolling your own in a language that makes this a lot harder.

I can't help but think the whole article is filled with bursts of dishonesty.

A language like C++, which let you use the proper data-structure in about two
lines of code, is _a lot easier_ when it comes to data-structures. While the
Go programmer implements a multi-map, priority-queue or red-black tree, anyone
else will have moved on to an actual topic of interest.

If you need a particular data-structure, surely having one ready in the
toolbox is a net positive, not a negative.

------
unsignedqword
I'm not much of a Go programmer but I would definitely regard Go's multiple
return and error handling (save the 'no assertions' clause) as very cool. I'm
not sure if any other languages have experimented with that approach before
the rise of Go, but to me at least it appears much saner than the prevalent
ridiculousness of exception handling.

~~~
herval
Some languages support tuples - you can also use stuff like ADTs to the same
effect. I think Go's advantage here is that it's the _only_ way to handle non-
panic exceptions, so you won't have systems where half of the errors are
handled with exceptions and half with returning tuples, for instance...(I
personally like the lack of "throwing exceptions" part, but find the multiple-
return somewhat exotic)

~~~
unsignedqword
Handling it as tuples is just as fine, but it's important that a language
intending to do so be devoid of verbosity and cruft. For example, D supports
tuples, but I would not want to attempt Go-style error handling in it:
[https://rosettacode.org/wiki/Return_multiple_values#D](https://rosettacode.org/wiki/Return_multiple_values#D)

You make a good point, too, that multiple-return being the only way to do
errors is more ideal than the language saying "oh, we support that, but we
also have exceptions, too!" At least in a language with Go's philosophy, you
can expect other people's libraries and your own code to play by the same
rules.

------
bpicolo
> Finally, in certain problem domains the power and flexibility of a hash-map
> is also unavoidable, therefore Go provides a Map built in

Not a fan of this sentence. Why try to make it sound like Maps are unusual or
bad? Just as fundamental as the list to real programming.

------
Myrmornis
> Custom data structures can be composed from the well understood builtins,
> rolled in under 100 lines of code and can can exist close to the place they
> are used (yes repeated!). The effect of this approach on readability,
> maintainability, decoupling, ... adds so much more value to the whole
> lifecycle, than the cost of the omission.

It's interesting to me that this philosophy comes from the Go designers at
Google, and that Google is also well known for keeping vast amounts of source
code advancing in lock-step in a single repository. From reading the recent
article on Google's source code repository structure, I believe that being
able to reuse code (e.g. data structure implementations) without versioning
headaches is one of the intended and actual benefits. It's of course not that
surprising that two different areas (Go design and repository structure) might
pull in two different directions, but these are two important high level
issues so it does seem a little inconsistent to me.

------
SZJX
> It is not ‘missing’ comprehensions, or inheritance, or generics, they are
> omitted (and I pray, always will be). In some way, in the context of the
> current fashion of returning to more functional languages, or the evolution
> of good old languages to include more functional paradigms (I’m looking at
> you Javascript and Python for two examples) then in a tenuous convoluted way
> Go has ‘innovated’ by avoiding that trend.

That's such a weird statement. If anything, those are likely more OOP-related
than FP-related, and he didn't really point out what's so bad about "more
functional paradigms", besides the implication that it might be harder for new
hires to pick up etc.

Anyways, I see that Go reduces the learning curve and simplifies lifecycle of
huge projects, but at considerable costs about language features and
expressiveness. I myself if working as a developer would rather not bear those
costs just for the sake of the whole clogs of the organization running a bit
more smoothly, and also so that myself would not just program day-in day-out
en masse with everybody else out there in an overly simplified language that
potentially puts me at more of a disadvantage in my career path. Maybe the
leaders of huge companies would have other thoughts and there will definitely
be developers who are happy to fill those roles, it's just not me.

------
bluejekyll
> “There is nothing new under the sun” rings true in all languages since the
> 80’s.

Really? Nothing? Sure a language like Rust has drawn from many other concepts
in other languages, but it has done so while actually bringing high level
features to a language that has zero overhead costs. But yes, it's not simple
like Go.

Did Go need to make all errors unchecked? There are no guide rails telling you
that you forgot to check an error result. This is a runtime thing you need to
discover. Is this actually simpler?

Go made the decision to allow for Null, even after nearly every other modern
language and other older ones are trying to kick it to the curb; Swift, Rust,
Scala, Kotlin, no nulls (the JVM ones have a compatability problem, as does
swift with ObjC, but still). Is it simpler to delay discovery of Null data to
runtime?

Go decided to not have generics, to keep the language easier to learn and more
approachable. It's hard to argue with this one. Like lambdas, it can be a
complicated concept to learn, but once you unlock this in you code, you write
less code and accomplish more. So yes, it's simpler, but at too high a cost
IMO.

To me the innovative feature of Go is the small runtime built into the binary
making deployment dead simple and easy. This is a million times better than
JVM, Ruby, Python, Perl, etc. This is a huge improvement over Java, and
something every language should have an option for. Ironically this is also
the least innovative feature, because this is how static binaries in C and C++
have worked for years.

I think this article is very well written, but I don't think it's fair to the
innovation going on in other languages.

(Disclaimer: I used Go, discovered the three primary flaws as I listed above,
and then searched for a better language. It would be fair to call me a hater,
usually I try to avoid this, but in this case that's fine with me)

~~~
dominotw
>innovative feature of Go is the small runtime built into the binary making
deployment dead simple and easy.

Is rust the only good alternative here to golang if you one doesn't want to
write c/c++ ?

~~~
rwmj
OCaml and Haskell build self-contained binaries, and have done for decades.
OCaml has very fast compile times, and an ordinary C-like linking system. You
can even directly link C *.o files. Go certainly isn't "innovative" here.

~~~
snaky
And if you don't need types, there's LuaJIT with all the dynamic features,
best inline C FFI ever done, runtime performance in par with native compiled
languages, and tools for producing self-contained binaries if needed -
[https://luapower.com/bundle](https://luapower.com/bundle)

------
danmux
The irony in all of these comments is that they almost all fall back to, or
start with, discussing language design, and on the whole ignore the tools and
processes that have a consistency from Go team to Go team. The value of this
power and consistency is probably overlooked in this and many other
conversations because they are complex to discuss, and it is simply easier to
focus on the almost provable value of the language features, missing or
present (maybe another availability bias at work?). The point of the article
was to try and refocus on Go as an engineering tool in a much broader context.

------
knucklesandwich
Accusing other languages of suffering from paralysis of choice and
fragmentation and offering "go get" as an example of solving this is truly
ironic: [https://github.com/avelino/awesome-go#package-
management](https://github.com/avelino/awesome-go#package-management)

~~~
IshKebab
Why? `go get` is an obvious _default_ choice for package management. You don't
have to make a choice.

There would be paralysis of choice if when you install Go you were forced to
choose from that list, but you aren't.

~~~
bobbyi_settv
I don't see how something that doesn't allow pinning versions can be an
obvious default choice for dependency management.

------
scriptproof
If you make a program that is executed a million of times or more a day, it
make sense to have a language that is "near the CPU", and allows to optimize
and speed up the most. This is what Go is. It will be a mistake to use it
elsewhere.

~~~
catnaroek
C++, otherwise a deeply flawed language, gives you more abstraction than Go
_and_ allows you to optimize and micromanage things more.

~~~
TillE
I love how C++ has had simple features like default arguments / function
overloading for decades, while modern languages like Go and Rust require
awkward workarounds.

Swift 3 looks good, though. They've learned the right lessons.

~~~
dominotw
C++'s problem was never 'not enough features' it was precisely the opposite.

------
behnamoh
I'm not a Golang programmer, but the mere fact that GOOG decided Java for
android is convincing enough that even GOOG does not believe in its Go.

(Frankly, I doubted that a little, until I realized Al-*-Go was not actually
written in Go!)

~~~
seabrookmx
Android predates Go. And it wasn't even started by Google.. Android was it's
own company and had already made it's decision on Java well before Google
decided to buy it.

Not to mention Go is focused on a different use case. Go is gunning for
microservices (with it's concurrency chops) and CLI based tools (being a
single compiled binary).. whereas Android apps are a totally different beast
that stands little to gain from either of those. In fact shipping multiple
binaries for different architectures is a bit of a detractor for Android
considering it supports MIPS, ARM, and x86.

> until I realized Al-*-Go was not actually written in Go!

Again, AlphaGo was based off technology from DeepMind, a company Google
acquired.

Please atleast do some quick wikipedia browsing before spewing FUD.

~~~
behnamoh
> Android predates Go...

So? Apple introduced Swift after Obj-C to make developing iOS apps easier.
What about GOOG? Couldn't they at least use Dart or Go (both of which they
developed) for android app development after Java? BTW, last time I checked,
they're still in for a lot to come from Oracle.

> Again, Al-*-Go was based off technology from ...

So let me get this straight. They bought a technology which was apparently
written in C++/JS and rewrote it in another lang, but then again, they did not
choose Go or Dart.

Seems like some one needs a wikipedia browsing...

