
Program your next server in Go - rjammala
https://talks.golang.org/2016/applicative.slide#1
======
fpgaminer
All of the server backends at my company are written in Go. This was a result
of me writing a couple servers in Python a few years back, ending up with lots
of problems related to hanging connections, timeouts, etc. I tried a couple
different server libraries on Python but they all seemed to struggle with even
tiny loads. Not sure what was up with that, but ultimately I gave Go a swing,
having heard that it was good for server applications, and I haven't looked
back. It has been bullet proof from day one and I am overall happy with the
development experience.

That was the good. The bad? Garbage collection, dependency management, and
lack of first-tier support in various libraries. Garbage collection makes the
otherwise lightweight and speedy language a memory hog under heavy loads. Not
too bad, but I have to kick the memory up on my servers. Dependency management
is a nightmare; honestly the worst part about it. The lack of first-tier
support in various libraries is a close second. AWS's API libraries had
relentless, undocumented breaking changes when we were using them, all on the
master branch of their one repo (breaking Golang's guidelines for
dependencies). Google itself doesn't actually have any real API libraries for
their cloud services. They autogenerate all API libraries for golang, which
means they're not idiomatic, are convoluted to use, and the documentation is a
jungle.

We continue to use Go because of its strengths, but it just really surprises
me how little Google seems to care about the language and ecosystem.

~~~
spriggan3
> We continue to use Go because of its strengths, but it just really surprises
> me how little Google seems to care about the language and ecosystem.

Go is certainly a language that is used at Google, but AFAIK a lot of
"Googlers" don't really like it and don't use it. It certainly not the
"official language at Google", given the weight of C++ and Java there. But
that's the consequence of being opinionated. Using Go means having Rob Pike
over your shoulder telling you how to write code. And he made sure you can't
escape that fact since there is no place for "ninja coding" with Go.

~~~
dtamhk
>> given the weight of C++ and Java there.

Python as well.

>> how little Google seems to care about the language and ecosystem

Let's compare with Microsoft. The top four out of five users at StackOverFlow
have top tags in C#, I guess Google have a long way to Go.

~~~
Pxtl
And yet the os group at ms is famous for their naked derision of the .net
Framework.

~~~
dtamhk
Hum .Net is their own dog food .. did you mean Android/iOS? :-D

~~~
dtamhk
What I mean was that M$ have competing offer to Android/iOS but it is not
getting the upper hand even within their own organization.

------
matthewmacleod
Go has been great for me at providing things like simple microservices,
network plumbing, CLI tools and that kind of thing. The C integration is also
super simple and makes it easy to wrap up third-party libraries.

It's also a bit tedious to write in practice. It's dogmatic, and that's
obviously a benefit in some ways but comes with the cost that quite a lot of
time in my experience is wasted fiddling around with program structure to beat
it into the way Go wants it to work. Dependency management is better with
Glide but still not perfect. The type system is quite annoying, and although
it's a cliche the lack of generics is quite annoying. Lots of silly casting to
and from interface{} or copy-and-pasting code gets old quickly.

Still, it's a great tool for its niches and I really think everyone should
pick it up and use it - the idea of simplicity it promotes is actually kind of
interesting, in contrast to the "showy" features one might expect of a modern
language.

~~~
ben_jones
Last night I was beating my head against the desk on some highly concurrent
code that involved each co-routine satisfying a simple rate limit, among other
things. Two hours later I had it working and the final implementation ending
up half the size of the original (~1k LOC -> 500 LOC).

I would upgrade your phrasing to: "frustratingly dogmatic in an ok way".

------
oconnor663
> When writing code, it should be clear how to make the program do what you
> want. Sometimes this means writing out a loop instead of invoking an obscure
> function.

For example instead of the obscure function

    
    
        a.reverse()
    

you can use the clear for loop

    
    
        for i := len(a)/2-1; i >= 0; i-- {
            opp := len(a)-1-i
            a[i], a[opp] = a[opp], a[i]
        }
    

:(

~~~
IshKebab
Yes there are clearly examples where the loop is less clear than the function.
But I think they wanted to avoid complex 'functional' code like this:

    
    
        Averager averageCollect = roster.stream()
            .filter(p -> p.getGender() == Person.Sex.MALE)
            .map(Person::getAge)
            .collect(Averager::new, Averager::accept, Averager::combine);
                       
        System.out.println("Average age of male members: " +   averageCollect.average());
    

From here:
[https://docs.oracle.com/javase/tutorial/collections/streams/...](https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html)

A lot of the time it is clearer as an explicit loop, _especially for other
people to read_. But it is annoying a lot of the time. I still think they
should add generics.

~~~
pjmlp
I can fully understand that example, only someone without FP knowledge would
not get it.

~~~
IshKebab
Exactly the point. And that was a fairly simple example. I've seen much worse
in real code.

------
avitzurel
I love Go.

It has become the default Go-To (pun intended) language for me for almost
anything that needs to be small and portable.

However, I don't see myself writing a full server with it, I would still
prefer a dynamic language like Ruby/Python for that and use Go for micro-
services CLIs and the rest.

For example:

Our main application is Rails, it communicates with SOLR as the search index,
in between the application and SOLR there's a proxy server that backups the
documents onto S3 and also does Round-Robin between slaves.

One other thing is that we use Go to communicate with all external APIs of 3rd
parties, the application code is rails and it communicates transparently with
a Go server that fetches the data from 3rd parties and responds to the main
application.

~~~
spriggan3
Go type rigidity makes Go code tedious to write. Instead of thinking "How can
we solve that problem" developers writing Go end up thinking "How can we make
the problem fit Go type system". I'm not even talking about concurrency here,
I'm talking about Types. Saying otherwise would be dishonest, unless one has
never used anything but C... Anybody who doesn't believe me just has to look
the reflect package. Reflection packages are usually a good indication of
language capabilities when it comes to statically typed ones.

It doesn't make Go a bad language,it has a some good percs, it's just
frustrating that its authors conflated simplicity with rigidity. Also I hate
when languages have hidden APIs, i.e. things the language can do that the
programmer can't. Go is full of these (for instance append which is a
parametric function since it knows the proper return type no matter what type
of slice you pass it, but you can't write your own? ).

It's good think that it requires very little investment to get started, but it
becomes highly frustrating when one stumbles on its limitations.

~~~
hesdeadjim
I've been writing Go daily for almost two years now and outside of wishing for
generics a few times I've never struggled to fit a solution into the type
system. I've certainly never considered going back to a duck typed language
like Python or Ruby. Not once. Not ever. We have slowly replaced even our glue
scripts that are written in Python with Go versions because maintenance and
understandability trump any perceived speed advantage of writing something in
Python.

~~~
IndianAstronaut
As soon as a system reaches a given size, not having static types becomes
unwieldy. Go's type system is great. Though my code still uses the var type
declarations.

~~~
hesdeadjim
The further I get away from Python the smaller that given size limit becomes.
After two years? It's at about 100 lines...

To me, the power of Go's simplicity is almost always underestimated by the
language's detractors. I can look at code my team wrote two years ago and with
a few <leader>gd's in Vim I know what's going on. Obviously Python fails this
test, but even a high-level static typed language like C# can suffer greatly
from all the magic one can invoke (Linq being a great example).

What it comes down to is that Go doesn't give you many ways to be clever.
Younger me who loved template metaprogramming in C++ would scoff at this
statement, but if you go back and have to reverse engineer your own cleverness
enough times you really, really start to dislike the practice.

~~~
mratzloff
Yeah, I find that Go has influenced my code structure for the better in other
languages. I'm much more likely to think carefully about a problem and
consider alternative approaches for simplicity before just dropping a
`template` keyword in C++, for instance. In Ruby, I am far less inclined to
reopen classes. Etc.

------
tokenizerrr
What about debugging? This is the major pain point for me. I've tried using
GDB, but...

> GDB does not understand Go programs well. The stack management, threading,
> and runtime contain aspects that differ enough from the execution model GDB
> expects that they can confuse the debugger, even when the program is
> compiled with gccgo. As a consequence, although GDB can be useful in some
> situations, it is not a reliable debugger for Go programs, particularly
> heavily concurrent ones. Moreover, it is not a priority for the Go project
> to address these issues, which are difficult. In short, the instructions
> below should be taken only as a guide to how to use GDB when it works, not
> as a guarantee of success.

[https://golang.org/doc/gdb](https://golang.org/doc/gdb)

~~~
muraiki
Have you tried out Delve?
[https://github.com/derekparker/delve](https://github.com/derekparker/delve)

I've only used it for simple cases, so I don't know if it helps with your
criticisms, but it was designed for Go. I mention this because it seems like
many gophers aren't aware of Delve.

~~~
arethuza
I've used Delve from the go plugin in PyCharm and it seems to work pretty
well.

------
shurcooL
I like slide 41 [0].

    
    
        What just happened?
        
        In just a few simple transformations we used Go's concurrency primitives
        to convert a
    
        - slow
        - sequential
        - failure-sensitive
    
        program into one that is
    
        - fast
        - concurrent
        - replicated
        - robust.
    
        No locks. No condition variables. No futures. No callbacks.
    

It's the ability to make these kind of transformations effortlessly at any
level, whenever I need to, that make me appreciate choosing Go when solving
many tasks.

[0]
[https://talks.golang.org/2016/applicative.slide#41](https://talks.golang.org/2016/applicative.slide#41)

~~~
brobinson
>No locks.

I'm sure the author means there's no _explicit_ locking done by the
programmer, but readers should be aware that channels are actually implemented
internally using locks (which are 4x slower than using a sync.Mutex yourself).

~~~
mappu
_> channels are actually implemented internally using locks (which are 4x
slower than using a sync.Mutex yourself)._

Is that for both buffered and non-buffered channels?

~~~
enneff
Channels are implemented using locks, but "4x slower" is a meaningless
microbenchmark number.

~~~
brobinson
You're welcome to benchmark it yourself. I got it from [1] which is a pretty
recent comparison.

[1] [http://www.jtolds.com/writing/2016/03/go-channels-are-bad-
an...](http://www.jtolds.com/writing/2016/03/go-channels-are-bad-and-you-
should-feel-bad/)

~~~
gizzlon
GP said meaningless, not wrong

~~~
brobinson
I found switching from channels to plain ol' queues to be an enormous
performance improvement in a program sending hundreds of millions of messages,
though I do agree in general that most programmers won't need to care about
it.

The program was a financial model backtesting framework which I ended up
rewriting in Rust because Go was simply too slow for what I wanted to do.

~~~
rodrigocoelho
Relevant: [https://www.datadoghq.com/blog/go-performance-
tales/](https://www.datadoghq.com/blog/go-performance-tales/)

~~~
brobinson
This is great, thanks!

------
nimmer
I'd love to see Nim on this diagram:
[https://talks.golang.org/2016/applicative.slide#13](https://talks.golang.org/2016/applicative.slide#13)
\- it could be close to the top right corner.

~~~
MustardTiger
The go devs are very careful to avoid mention of all the other languages that
compete in the same space and are significantly better.

~~~
geodel
I'd love to hear about those languages.

~~~
i_feel_great
Erlang and Ada are two that I consider superior to Go.

------
robohamburger
I will have to try Go again. It seemed really awesome at first then quickly
seemed like a regression in a lot of PL design things (which is good in some
cases). I personally like rust but maybe I am a glutton for type based
punishment.

 _Solution: design the language for large code bases_

This seems crazy but whatever works. I would assume that would only buy you
some wiggle room inside whatever order of magnitude of committers you have. It
seems like eventually you would need to split up the code base if you are
having contention issues.

------
yanilkr
I once tried to convince an enterprise java developer to give golang a try.
The guy passionately hated it and the reasons were very very petty. The other
younger engineers who did not have prior bias loved golang and they were
productive so fast.

The person truly had a java supremacy attitude that was very difficult to deal
with. Golang is a kind of shift in thinking that you have to first unlearn
your existing ways of thinking and then you will have a place for it. Some
people are not willing to take that leap of faith unfortunately.

~~~
kmiroslav
> you have to first unlearn your existing ways of thinking and then you will
> have a place for it.

Unlearning is not always acceptable, especially when you have to unlearn sound
and proven practices, which Go often requires to do.

I think it really depends where you're coming from: people coming from
dynamically typed languages like Python and Ruby are quite happy with Go since
it's a small ramp up on the type ladder, but anyone who's used to static types
and generics will usually see Go as a step back and refuse to take that step
(for good reasons in my opinion).

To draw an analogy, imagine a Go developer is being asked to switch to Python
and in order to convince them, you tell them they just need to unlearn a few
things. To them, you are asking them to give up types and other practices that
makes their code more robust, so it's not an acceptable argument.

~~~
weberc2
> especially when you have to unlearn sound and proven practices, which Go
> often requires to do.

Such as? I'm not really sure what "sound and proven practices" a Java
developer would have to "unlearn" to adopt Go. Most of the differences between
Go and Java amount to removing features that 20 years of Java experience have
proved to be unsound or unnecessary (inheritance and exceptions, for example).
From a feature perspective, Go is mostly a subset of Java. The features Go
adds are mostly related to concurrency, and I've not heard anyone say Java
does concurrency better than Go.

~~~
eropple
I'll say that Java doesn't do currency _worse_ than Go, that's for sure. It
has all of the primitives in whatever arrangement you want to put them
(Javaflow and now Coroutines if you want go-I'm-sorry-coroutines, native
threads if you want those, and Go channels can be implemented in maybe two
dozen lines), more flexible, battle-tested abstractions (such as Akka offering
you an asynchronous, message-passing actor model, which could be written in Go
but seems in practice to be passed up in favor of channels), and tooling
around these that I find to be head-and-shoulders better than anything Go has
(like multi-threaded debugging).

I've basically (willingly or unwillingly) turned into a Ruby person over the
last few years, as neither Go nor the JVM really have a _ton_ to offer me
right now, but I don't think a fair comparison of concurrency-related stuff,
either in terms of tooling, libraries, or the language itself (I'd give Go
this, except that you can't build an unbounded buffered channel and at that
point the use of channels for what I write rapidly approaches zero), is nearly
as clear as you assert.

~~~
colin_mccabe
Java's concurrency story is weak overall. Nearly all code still uses the old-
style "synchronized" blocks, rather than ReentrantLock. This shouldn't be a
big surprise, considering that ReentrantLock was only introduced recently.
With synchronized blocks, you don't have any way of releasing the lock other
than by exiting the block, which leads to some very contorted-looking code.

The fact that you can synchronize on literally any object means that your
object lock is effectively part of your public API. Some other piece of code
can easily grab your object, synchronize on it, and then start calling your
methods, assuming that this will be atomic. And if you change to use a
different lock later, it will break.

Sure you could use BlockingQueue to get some of the benefits of Go channels.
But the standard library and pretty much any software you'll interact with
were written before BlockingQueue existed, so they won't make use of it. You
will have to fight your lonely crusade to use message passing on your own.
Which in practice means that you won't be using message passing, just plain
old mutexes and volatiles.

In Go, all code runs in goroutines which get multiplexed to kernel threads. In
Java, nearly all code is blocking and uses an entire kernel thread. Sure you
can use NIO to write an event loop-- just as long as you're careful to never,
ever call a blocking function. But nearly every interesting function in Java
can block. Including the DNS lookup functions Java provides.

~~~
kmiroslav
> The fact that you can synchronize on literally any object means that your
> object lock is effectively part of your public API

I'd argue that the fact you can lock on any object is a strength. These days,
hardly any Java developer will use synchronized on methods and instead prefer
the idiom:

    
    
        public class A {
            private Object lock = "";
    
            public void foo() {
                synchronized(lock) {
                }
            }
    

This allows Java code to be extremely granular in what gets locked, which has
enabled very powerful multithreaded constructs and libraries such as
ForkJoinPool and many others described in the Java Concurrency In Practice
book.

------
capote
How do the bullet points in "Why does Go leave out those features?" address
why Go leaves out the features on the preceding slide?

All it talks about is clarity (important but not the only important thing) and
I just don't see how any of the left-out things are _inherently_ unclear. I
think you can write clear and unclear code alike with all of those left-out
features.

------
cryptos
There are some questionable statements:

> Go differs from Java in several ways

> Programs compile to machine code. There's no VM.

This tries to imply that having a VM is a bad thing.

> Simple, concise syntax

The syntax is simple, but not overly concise. For example the lack of generics
leads to a lot of repetition.

> Statically linked binaries

You can have them with Java, too.

> Built-in strings (UTF-8)

Should this suggest that Java doesn't have trings?

> Built-in generic maps and arrays/slices

Yeah! Some of the most awesome things about Go is the limited set of data
structures and the limitation of generics for exactly this few structures.

> Built-in concurrency

It is questionable whether this is good or not. There are a lot of good
concurrency libs for the JVM.

> Sometimes this means writing out a loop instead of invoking an obscure
> function.

This is completely strange! The lack of abstraction is sold as a good thing.
Actually a lack of abstraction leads to redundant and error prone code.

~~~
wjagodfrey
In regards to your last comment, abstraction is a good thing but there's a
conversation to be had around quality of abstraction. Good abstraction doesn't
age, or at least ages very slowly. Lack of abstraction in languages leads to
innovation and iteration, that then leads to good abstraction. We are general
too quick to assume that a new thing is good abstraction. Better, in some
cases, to leave abstraction discovery in userland, as good abstraction is
rare. The cost of poor abstraction within a language is API and cultural
lockin, when better solutions are found.

------
zZorgz
I had a PHP program that processed HTTP requests and stored some data onto a
local database, and decided I needed to rewrite it for various reasons so I
decided to choose Go. Some points I recall:

* Static typing is good.

* As I expected, the standard library and other packages available had the http & routing stuff I needed, which is all good.

* I like that errors are specified in function signatures, unlike exceptions in languages like ruby/python.

* I don't like errors being easily ignored, and return values being assigned default or arbitrary values. I once may have also accidentally used the wrong equality operator against nil.

* Defer is nice, but would be better if it was based on current {} scope.

* Append on arrays? has very bizarre semantics sometimes mutating or returning a different reference.

* Initially I ran into trouble reasoning how to use some sql package and ran into "invalid memory" deference issues or some such when passing a reference. Thus, I'm skeptical about "memory safety."

This was only a simple program though and turned out to be worthwhile for me
in the end.

~~~
xcombelle
memory safety imply that if you do something bad you will be stopped (with
"invalid memory" issues for example), not that it is illegal to write
something bad

~~~
zZorgz
Well I am also then interested in it being hard or illegal to write something
bad :)

------
thom
Holding up Perl and JavaScript as examples of languages that are 'fun for
humans' makes it pretty clear I'm not the target market.

~~~
the_common_man
Can't speak for perl because I have only seen some horribly complicated code
in it (which probably speak more of the author and not the language itself)
but what's not fun about JavaScript ?

~~~
jonathankoren
I used Perl for years, and it's still my go to language for quick text
parsing. I stayed away from the bizzare "object oriented" syntax (They're not
classes. They're packages, just called with arrow operators instead of like
normal functions. But being Perl, you can just use the package and call the
functions yourself because TMTOWTDI! (Blech.)) Also Perl's support (or at
least Perl 5 (Does 6 even exist? It's like a unicorn like Duke Nukem Forever
or Guns-n-Roses Chinese Democracy, only those eventually got released.)) for
complex data structures (including multidimensional arrays) requires explicit
reference instanteation and dereferencing, like C pointers. It's the biggest
pain point.

~~~
sulam
I am no Perl apologist, but they DID finally release Perl 6:

[https://perl6advent.wordpress.com](https://perl6advent.wordpress.com)

------
PeCaN
What are some cases where I would choose to write a server in Go instead of in
Erlang?

~~~
zxcvcxz
First thing on duckduckgo when you search for how to write a server in erlang:

[http://20bits.com/article/erlang-a-generic-server-
tutorial](http://20bits.com/article/erlang-a-generic-server-tutorial)

That's just ridiculous. Erlang looks like php and python had an unholy child.

~~~
joshrotenberg
I won't downvote you because you are certainly entitled to your opinion, and
there is no way I'm going to get into an Erlang vs Go For Writing Servers
argument, but if you immediately write off Erlang/OTP because of how it looks,
you are going to miss out on some pretty amazing server writing functionality.

------
fauigerzigerk
_" >50% of code base changes every month"_

I wonder what unit is being counted here. I don't think it's possible to
actually review and rethink 50% of what has been created before. That's just
not sustainable.

~~~
robotresearcher
> 5000+ developers across 40+ offices

That's an _enormous_ amount of manpower.

~~~
fauigerzigerk
That doesn't matter. Only growth of manpower matters. The fundamental problem
stays the same regardless of how many people you have.

If you add code and revise 50% of it every month, the code base is bound to
grow and the share of time spent on maintaining the old code grows as well
until development of new code grinds to a halt.

Unless of course there is massive growth in hiring. But that isn't
sustainable.

[Edit] Well, I forgot one possibility: Deleting code.

~~~
Jabbles
[https://www.theatlas.com/charts/4ySTybWY](https://www.theatlas.com/charts/4ySTybWY)

(Can't vouch for accuracy.)

------
iagooar
One important niche I see that Go serves very well is in distributed, fault-
tolerant deploy platforms (aka schedulers), like Kubernetes or Mesos. If you
look at the amount of tooling that uses Go, you almost feel there just is no
other choice out there.

I would not adventure to say state-of-the-art schedulers would not have been
possible without Go, but for sure Go fits the requirements pretty well.

~~~
simeonf
> I would not adventure to say state-of-the-art schedulers would not have been
> possible without Go, but for sure Go fits the requirements pretty well.

AFAIK Mesos is mostly written in C++. Aurora - a Mesos framework & scheduler
from the same folks is written in Java & Python.

~~~
iagooar
Yes, what I meant is that a lot of tooling around those is done in Go.

------
voltagex_
Can anyone convince me to use Rust over Go, or the other way around?

My target machines range from i7s with massive amounts of RAM to Raspberry Pi
with slightly-less-massive amounts of RAM.

~~~
shadowmint
I think the tldr; of this (often raised...) argument boils down to:

    
    
        Don't use rust if you're asking that question.
    

If you _could_ implement your solution in go or rust, then go is probably a
more appropriate choice; it's a good high level solution for high level
problems.

Rust is not a good solution for high level problems; it's a good solution for
low level problems where go would be a terrible choice; and it's a good
solution for high level problems where other choices are even worse (eg. C++).

They're both good languages, and you'll _learn way more_ from picking up rust
than you will from picking up go, so if you're just screwing around and want
to learn a language this year, absolutely, pick rust or clojure. Go isn't on
the list for 'interesting programming languages'.

...but if you have an actual problem you're trying to solve, I would be hard
pressed to enumerate the reasons why you would pick rust if the problem was
solvable using go. Maybe because your C dependencies would be easier to call
from rust than go? That's all I can think of.

~~~
stymaar
> Rust is not a good solution for high level problems

Who is saying that ? Not the Rust team, nor the Rust users … Rust is a general
purpose programming language, and it's pretty high-level (in terms of
features, think about functional programming for instance). The only reason I
wouldn't advise everyone to write their stuff in Rust atm, is the youth of the
ecosystem (which is growing rapidly, but is still a bit too early-stage):
their is no intrinsic limitation in the language that make Rust «not a good
solution».

~~~
shadowmint
I'm saying it.

The piston developers are doing what right now? Writing a _new programming
language_ (dyon). Why are they doing that? Because rust is great for
prototyping games in? no.

...rust _is_ verbose. It _is_ statically typed, it _is_ less productive than
some other languages and it _is_ hard to learn.

Now, you get a whole lot of other benefits in exchange for that, absolutely,
and technically speaking, rust is a super awesome and sophisticated language.

...but _right now_ , it has neither the ecosystem nor simplicity for picking
up and _practically solving high level problems_.

If you have a problem, right now, you want to solve: pick go.

... _unless_ your problem is something that rust would be better at, and those
things are low level things, like building game engines, not high level things
like building web applications and cross platform desktop chat applications or
machine learning solutions to driving cars.

You _can_ build high level applications in rust, and in C++; the point I'm
making is that unless you actually have a reason for picking them (and there
are plenty...), don't.

Pick the tool for the job; rust is a great tool for the right job.

Go is a better tool for a lot of applications; and a totally useless one for
others.

/shrug.

We don't need to pretend rust is general high level language you should pick
up and use for any problem domain. It's not. You're shooting yourself in the
foot if you use it as though it was.

~~~
stymaar
> The piston developers are doing what right now? Writing a new programming
> language (dyon). Why are they doing that? Because rust is great for
> prototyping games in?

I agree with that, Rust is not a scripting language. Dynamically-typed
scripting languages have proven their efficiency for prototyping.

> rust is verbose. It is statically type, it is less productive than some
> other languages

Than scripting languages yes, but it's exactly on the same side than Go on
this point. Scripting languages are extremely convenient for small projects,
but are more difficult to maintain in the long run if the project grows too
big. (I personally live coding JavaScript, and a the project grows we are
progressively add a static-typing layer (flowtype.org) to our code for the
sake of maintenance).

> it has neither the ecosystem nor simplicity for picking up and practically
> solving high level problems.

There is a real trade-off between scripting languages (Python, Ruby and
Nodejs), and statically-typed ones (Java, Go, and Rust), but it's not related
to being high-level or not. In term of abstractions and features, Rust is at
least as high-level as Java & Go.

> If you have a problem, right now, you want to solve: pick go.

We are using some Go at my company because we wanted to follow the trend, but
frankly unless you want to built a simple system with no dependencies, Go is
not ready to solve problem «right now» either, because the ecosystem is still
really poor. If you have a problem, right now, you want to solve, you should
probably still pick Java over Go, even if a lot of people (me included) don't
like Java … Basically I think Java is the most important factor of success of
the Go language: Go feels like Java, but in a younger and trendier way.

> We don't need to pretend rust is general high level language you should pick
> up and use for any problem domain. It's not. You're shooting yourself in the
> foot if you use it as though it was.

Rust is a «general high level language», with the same high-level generality
than Go or Java.

I bet one can chose any* Go or Java code sample, and rewrite it in Rust with
around the same amount of code and without introducing any memory issues (what
you wouldn't be able to do in C or C++). I think that's a good illustration of
Rust being a «general high level language».

*unless it depends on a library that has no equivalent in Rust (as I said before, the youth of Rust's ecosystem is the reason not to use Rust in S1 2016).

> and it is hard to learn.

It is indeed, no discussion about that.

~~~
lossolo
> (what you wouldn't be able to do in C or C++)

I would and many more people also would but for sure it would be harder/more
complex in C/C++ than in Go. You wrote that as it would be impossible to do it
in C or C++ which is not true.

~~~
stymaar
Of course it's possible to do the same thing in C, but most likely not with
«the same amount of code», nor with «memory safety». ;)

~~~
lossolo
> nor with «memory safety»

I've wrote that you can do it with memory safety which is possible BUT it's
more complex in languages like C/C++ that do not guarantee memory safety (it's
your responsibility). If it was not possible then you would not have anything
on your screen right now. I am writing that because someone that is not
familiar with those languages would get impression from your comment that
memory safety is impossible in C/C++ which is not true.

------
squiguy7
> Clarity is critical.

When you need to write high performance code this is a great maxim. I enjoy
the simplicity of Go and the guarantees it provides. Being able to reason
about code and not having to guess is a win for any development team.

~~~
ridiculous_fish
IME, clarity and reasoning are weak points of Go, relative to other systems
programming languages (but perhaps not to dynamic languages):

1\. Slices make it hard to reason about aliasing. bar = append(foo, val): does
bar now alias foo? The answer is the worst possible: "sometimes."

2\. Closure semantics make it hard to reason about thread safety. I converted
this serial loop to parallel using goroutines; did I introduce a race
condition? I have to look at each variable to decide. (Any sort of const
capturing would go a long way here).

3\. Goroutine leaks can be hard to reason about. For example, a channel that
is not sufficiently buffered can result in a leak.

4\. Nullable maps and channels reduce clarity.

5\. The "redeclare" semantics means := sometimes does not introduce a new
variable

~~~
squiguy7
I didn't mean to gloss over the go routine problems. You're absolutely
correct, when there exist tools like the race detector it makes it evident
that you can write incorrect concurrent programs. Becoming proficient at using
the concurrency patterns in Go takes time but it is an advanced topic.

Thanks for writing up these common mistakes.

~~~
colin_mccabe
Those aren't common mistakes, just things he dislikes about the language. For
example, I don't care whether := sometimes does not introduce a new variable
(have never had a bug related to that). I don't find the closure semantics any
worse than Java's (sure Java requires captured variables to be final, but it
doesn't require them to be immutable).

I find append's semantics to be pretty intuitive. But then again, I'm familiar
with realloc in C, which is where it came from. At any rate, slices are
references to an underlying array. If you are making one slice from another
slice in a way that potentially doesn't involve copying, you should expect the
new thing to alias the old thing.

People often complain about channels having limited buffer sizes. But if
channels had unlimited buffering, they'd complain about memory leaks and
inefficiency.

A list of common mistakes in Go would be interesting. It would probably start
with the "assigning a typed nil value to an interface leads to interface !=
nil" wart.

~~~
blub
They seem to be language issues which make development more error-prone.

And dismissing them just like that won't make them go away :)

------
BooneJS
I use Go exclusively for command-line applications, previously using Perl
(ducks). It's a fairly simple language, you can pick it up quickly, and
gofmt/godoc/etc are useful utilities in reducing friction.

------
moyok
I really like go. I just love that it compiles to a native binary and is so
easy to distribute. I love the way interfaces work and that types specify
interfaces automatically without explicitly specifying that.

I love the "strictness" of the language - for example the code won't compile
if you declare a variable and not use it, or import a library and not use it.
I love that there is a standard gofmt which means code auto formats to a
standard format. These features really help set some "discipline" when working
in a team.

I love the way concurrent code can be called easily and the use of channels. I
love the performance - it has been more than fast enough for my use cases so
far. I love that I can get started with an HTTP server using just the standard
library, and the most popular web frameworks in go are micro frameworks.

Overall, there's a kind of a simplicity about the language that underlies all
of the above things, and that is what makes me excited about go.

I have used go in some minor projects that have been running peacefully for
months without any hitches, and am using it in a big project mostly in the
form of microservices and scripts. It has become my favorite language now.

------
dicroce
"Sometimes this means writing out a loop instead of invoking an obscure
function."

I can't help but think this is specifically a dig in C++'s direction. Since
C++11 lambda's I've been using <algorithm> a lot more and I don't think you
could get me to go back at this point... Yes I had to learn exactly what a few
methods do, but now I have beautiful straight line code...

------
moron4hire
I've been experimenting with this concept with C# recently [0], where I have a
small backend written in C#, exposing a simple, RESTful HTTP server, that
automatically finds itself a local port to run on and opens the default
browser to a default page.

It's actually kind of nice. Until I did this the first time, I hadn't realized
just how much bullshit I had previously put up with, with setting up local web
servers, trying to get configurations down, etc., etc. At some point, I think
most web framework's configuration options just got too complex to be
considered _configuration_ options and became weird, poorly defined scripting
languages for defining web servers. Having a real programming language to do
that instead is just a wonderfully smooth experience.

Some things I plan on implementing with it:

* local file system access, to ultimately implement an FSN [1] clone in my WebVR project.

* my own Leap Motion WebSocket service, because the default one doesn't use the latest Orion beta and its associate JS library is complete garbage.

* A similar dude for MS Kinect data.

* Ultimately, get the previous two to run over WebRTC instead (not easy, there is no WebRTC library for Windows outside of major browser implementations) to be able to stream their respective camera data.

* Live raytracing of model textures for baked lighting in scenes in the WebVR session.

Right now, it's just a source file I drop into a standard C# console project.
I'm thinking about making it a full-on library, though at this point there
isn't much need.

[0]
[https://github.com/capnmidnight/HereTTP](https://github.com/capnmidnight/HereTTP)

[1] [https://en.wikipedia.org/wiki/Fsn](https://en.wikipedia.org/wiki/Fsn)

------
justinsaccount
> Lingo: Logs analysis in Go, migrated from Sawzall

Would love to play around with this

~~~
mikecb
As far as I could find not open sourced, but talked about at the data science
blog (which is generally awesome):
[http://www.unofficialgoogledatascience.com/2015/12/replacing...](http://www.unofficialgoogledatascience.com/2015/12/replacing-
sawzall-case-study-in-domain.html)

------
poorman
_server is a pretty loose term. Most_ servers* these days require some sort of
full stack, with frontend, ORM, etc... Go adds a lot of development time if
you need all of that. ...On the other hand, one off tiny microservices, it's
absolutely great!

------
inglor
The slides are awesome and I really am fond of go, but the examples using
channels are all more code to write considerably than I'd write in C# or
JavaScript with async/await and not any more robust or safe.

Go is great for actor based systems where you model things using channels and
goroutines for what they stand conceptually - not when you use it to simulate
Task.WhenAll/Promise.all with a timeout.

I think _that's_ what they should be selling - that your server's architecture
should typically be different.

~~~
weberc2
Yes, but in Go you don't have to deal with the [colored function problem][1],
and the code to parallelize I/O is no different than the code to parallelize
computations. I agree that these examples don't do justice to Go's concurrency
facilities--the most compelling examples are probably too complex for a slide
deck.

[1]: [http://journal.stuffwithstuff.com/2015/02/01/what-color-
is-y...](http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-
function/)

~~~
inglor
The code to make I/O concurrent _should_ in my humble opinion look different
from the code to parallelize computations since well - in I/O you only care
about concurrency and in computation you care about parallelism.

~~~
weberc2
It's not obvious to me why this distinction is useful. Could you explain?

------
yvsong
Any comment on Swift vs Go, potentially for server programming?

~~~
jsmith0295
I don't think Swift is particularly mature in this area yet, and it's
concurrency depends upon Grand Central Dispatch. Go on the other hand is
rather mature, especially for its age.

Other than that, it really depends on what the server is for, but in general I
would say Go is probably a better choice.

If you're interested in something similar to Swift for the server, I think
Kotlin w/ Spring Boot would probably be a safer bet at this point.

------
chuhnk
Go is a phenomenal systems programming language and becoming quite useful as a
general programming language too. It's clear from the projects that are now
coming into existence that Go lends itself well to the world of distributed
systems and from the language design you can see that it was created with
network programming in mind. The fact that concurrency is built into the
language and errors are treated as values that should be dealt with just
highlights those facts.

We used Go at Hailo for our microservices platform and it served us incredibly
well. I've gone on to create an open source project called Micro
[https://github.com/micro/micro](https://github.com/micro/micro) that builds
on those past experiences. It's just a joy to write micro services in Go.

------
sly010
Go is my secret and I wish less people used it, so I had an advantage over
them ;) Edit: typos

------
Matthias247
The presentation focuses a lot on [web] servers and google scale, but I found
that Go also works quite well for applications/services on embedded linux
systems.

Main pros for me there are:

    
    
      - Easy to cross compile and deploy  
      - Daemons often need to do a lot of communication (some also for providing web APIs) and need to embrace concurrency. Both are covered very well by Go's ecosystem.  
      - Compile-to-binary eases distribution concerns in cases where you want to avoid to publish all source code (and thereby know-how) compared to VM languages or scripting languages.

------
epynonymous
golang is great, i use it to do 3 things thus far: restful api server
(net/http, gorilla mux), dynamic web server (net/http, amber, sql), and
websocket server (net/http, gorilla websocket, redigo/redis). the libraries
are well implemented, the syntax is beautiful imho, and i'm able to quickly
write code similar to interpreted languages like ruby, python, but scale much
higher. i used to do lamp, then shifted to python tornado, ruby sinatra,
nodejs/expressjs, but find golang to just be more compact and fast. my sinatra
environment required rbenv, gems, and i just wasn't impressed with it.

what i like the most about golang is that the end result is a binary where my
production server doesn't need to have any dependencies except for the ability
to run elf binaries. i like having this option, but in reality the binary size
gets pretty unwieldy for upload, so i actually end up doing a pull on the
source code, compiling and starting up.

package management has not been a problem for me.

i do find html template packages to be a bit deficient, amber, ace, there are
ports of haml and jade, but they all seem pretty half baked. i had to have a
lot of hacks in my code to get this stuff working.

also sucks that there isn't a standard orm, but i can hang and keep up with
raw sql.

the language expressiveness is not as convenient as say ruby, but it's pretty
close.

------
warcode
I always see Go promote Clarity/Readability and yet in the second example its
already "fmt.Fprintln". That is not easily readable for humans.

------
VeejayRampay
I wonder why on that fun/fast diagram, it appears as if Perl faster than
Python, which is faster than Ruby. They're all about as slow.

------
satysin
The only place I would want to use Go is for a server tbh. It isn't all that
great for anything else imho.

~~~
avitzurel
It is amazing for dev tools and CLIs.

Perfect example for this is Hashicorps products, taking out Vagrant it is 100%
written in Go.

Having a single executable tool that you can download and run anywhere is
super powerful. You develop once and you build it for every system. It's the
definition of delight to me.

~~~
kasey_junk
I'd argue that CLI tools are really a _better_ example of what Golang is good
at.

Most of the things purported to be major wins for Golang on the server side
are available or better in other environments.

For CLI programs that need to be a little more sophisticated than bash Golang
is quite nice.

~~~
avitzurel
Agreed. Check out my comments on this threads...

------
sargas
The fast/happiness graph of languages is pretty interesting.

Unrelated: Rust would probably be around the right-most area in the horizontal
axis, close to C and C++, and a little below Go in the vertical axis.

------
insulanian
Which kind of applications does one write in Go? Asking this from perspective
of a developer working mostly on business apps with Angular frontend and .NET
(C#/F#) backend.

~~~
spriggan3
If you use C#/F# you don't need Go, .net is coming to Linux by the way so you
definitely don't need Go.

With Go you'll basically have to rewrite asp.net from scratch if you're used
to that, because frankly the ecosystem is poor if you don't stick to data
transformation/ marshaling with an HTTP server. No full featured ORM, no good
Logging library, no Razor like view layer, piss poor web frameworks and an
extremely rigid language with a rigid type system if you are used to F# and
C#. The only advantage of Go is the fact that you can deploy a single
executable with no dependencies on a server. That's it.

~~~
insulanian
Oh, I definitely don't want to switch to Go :-) I did take a look at it once
and decided that it is not for me.

That being said, I still wonder what types of applications are so suitable for
Go that people decide to use it instead of other languages?

------
bfrog
Go is a fine language and a very good run time, though having written a large
program with it I've learned its warts well enough to not want to use it again
personally.

------
hobo_mark
I might have strange requirements for a server, but I need rdma, verbs,
libfabric... Is there any way to use them in an idiomatic way in go?

~~~
kkirsche
Not that I know of. That sounds like it goes against much of what Golang
builds around and the areas I've had to hook into low level areas such as the
kernel for NetFilter required me to go down to C

------
callumjones
I think "Program your next server in Go" is a little too broad, the specific
language features that Go explicitly leaves out makes it hard to build an
extensive backend server. Go is best suited to use cases listed in these
slides: simple services that do very focused things.

I love Go and used it to build some very useful web hook and CLI tools. It
just doesn't lend itself to something where you expect to have a vast set of
APIs under one Go project.

------
aj7
Can't read on IOS

------
codedokode
Here are the problems I had when tried to write a simple CLI utility (tool to
run any program in seccomp-bpf based sandbox) in Go:

\- using case of a first letter of identifier as a public/private flag. You
end up with half names starting in a lowercase letter, half in an uppercase
(the code looks inconsistent) and forgetting how to spell them. And having to
rename the function everywhere when you decide to change it from private to
public.

\- no official package manager. Unclear how to add external libraries to your
project and how to set specific version you need. I ended up adding necessary
files into a separate folder in my project.

\- Go manual suggests you have single directory for all projects and
libraries. That was inconvinient because I develop on Windows and use Linux
only to test and run code in /tmp directory, I do not keep the code there. And
why would I want to keep unrelated projects inside the same directory anyway?

\- no rules how to split contants, types and functions into files and folders.
For example in PHP there are certain rules: each class goes to its own file
and you always know that class Some\Name is stored at src/Some/Name.php. Easy
to remember. And in Go you never know what goes where. Large projects probably
look like a mess of functions scattered around randomly

\- no default values for struct members, no constructors

\- no proper OOP with classes

\- standard library is poor

\- open source libraries you can find on github are not always good. I looked
for library to handle config files and command line arguments and didn't like
any.

\- standard testing library doesn't have asserts

\- easy to forget that you need to pass structures by pointer (in OOP objects
are passed by reference by default). And generally use of pointers makes the
code harder to read and to write.

\- weird syntax for structure methods. They are declared separately from the
structure.

\- go has 2 assignment operators (= and :=) and it is easy to use the wrong
one

\- having to check and pass error value through function calls instead of
using an exception. So most of functions in your code will have two return
values - result and error

\- no collections library

\- simple things like reading a file by lines are not so simple to implement
without mistakes

\- static typing is good but sometimes you cannot use it. For example I wanted
to have the options in a configuration file mapped to the fields of a
structure. I had to use reflection and every mistake lead to runtime panic.
And you cannot use complex types like "pointer to any structure" or "pointer
to a reflect.Value containg structure" or "list of anything" or "bool, string
or int".

Of course Go has also many good parts that might outweight its disadvantages
but I am not writing about them. For example I have not used goroutines but
they look like a simple solution for processing async tasks or writing
servers.

I think Go is not ready yet for writing large applications. It might be ok if
you write a small utility but I cannot imagine ORM like Hibernate or web
application written in Go.

Also I took a look at the code in the presentation. I wouldn't want to write
such code. For example, here
[https://talks.golang.org/2016/applicative.slide#20](https://talks.golang.org/2016/applicative.slide#20)
they use static methods (http.HandleFunc(), log.Fatal()) instead of instance
methods. So you cannot have two logs or two servers. Using static methods
everywhere is bad especially in large applications. Google itself uses Go only
for small utilities like simple proxy servers.

~~~
mratzloff
Many of these points are simply wrong, or confused.

------
naivepiano
I'm afraid HN has a serious problem with downvoters. Why -in heavens name- is
the above a question that deserves downvoting? UPDATE: whoray - I got
downvoted too. Gee man. Just not worth it. Buy and thanks for the fish.

~~~
dang
We detached this subthread from
[https://news.ycombinator.com/item?id=11856539](https://news.ycombinator.com/item?id=11856539)
and marked it off-topic.

