
Why Go and Not Rust? - kristoff_it
https://kristoff.it/blog/why-go-and-not-rust/
======
pornel
Not disagreeing with the sentiment, but I dislike the word "simple" used to
describe languages, because it has two meanings: simple = "consists of few
parts" and simple = "easy to use", and these are _not_ the same.

Certain things in Go are _not easy_ (not simple), because Go has _few language
features_ (is simple).

Go has definitely a lower barrier to entry and is very productive for certain
size and complexity of a project. However, as you start pushing beyond "scale"
Go is designed for, Go becomes less simple to use. To appreciate things like
generics, non-nullable types, no shared mutable state, you have to be working
on a problem that requires these things, and only then these extra features
pay off and make development and maintenance easier.

~~~
MuffinFlavored
Can somebody post an example of when you would use generics to solve a problem
in the real world, and how that would be implemented in Go instead?

~~~
killbot5000
The simplest example I can think of is: Map(slice, func)

You can can implement this generically in Go using interface{} types and
runtime type checking, but then you have runtime type checking failures.

A java/c++-esque "generics" implementation would be able to type-check at
compile time.

~~~
ori_b
You can implement it in Go using loops, and it's not significantly slower or
more error prone.

~~~
crimsonalucard
Yeah but you can't implement it generically.

That means for every conceivable input type and output type combination you
have to have a new MAP or REDUCE function to handle it.

All Modern languages except golang and elm only require one implementation of
MAP that can handle all type combinations.

It's called parametric polymorphism.

~~~
excursionist
Elm has parametric polymorphism.

~~~
crimsonalucard
you're right. My mistake.

------
asdkhadsj
As a now Rust lover and prior (6 years?) Go lover, this article hits home. We
have a lot of tech debt in my shop _(who doesn 't lol)_, and generally I
advocate Rust or Go. I usually start the conversation with: Would this be a
program you'd write in C++ or in Python? And then I advocate Rust or Go, with
one amendment; data structures, and frequency of conversion/etc.

Having converted some large Go programs to Rust recently I now have the
perspective that some programs, while perfectly fit for Go, are miserable to
write without Generics. I had a program which did some pretty minor work, but
it did so with a lot of varying data structures and writing it in Go was less
than pleasant. No, Go might handle this better with generics. However I
imagine this will only move the bar. Certain problems are just going to be
friendlier _(though, more complex!)_ to solve with a more advanced typing
system.

I do look forward to the day that Go can get basic iterator behavior via
Generics _(if ever)_. Some of the smallest things in Rust were the biggest
sighs of relief for me. Converting a slice of slices from one type to another
is just a PITA in Go _(in my opinion)_ , and iterators make a world of
difference for short, easy to read and comprehend implementations.

In my experience, Go's biggest fault is code bloat that "simplicity" offers. A
simple goal could turn into a multi function implementation in Go that frankly
shouldn't have to be. Then code locality gets worse over time, and suddenly
simple doesn't feel simple. Rust's larger complexity (iterators and the like)
improve code locality, and thusly simplicity, in my experience.

It's a game of tradeoffs. They're both great languages, and they both have
their places in my company.

~~~
ShinTakuya
I'm a Rust evangelist too but I think it's going a bit too far to blanket
recommend Rust and Go over C++ and Python. Python in particular is still an
excellent language and there are many situations where it makes perfect sense
to continue using it.

I can see a future where Rust and Go overshadow Python but that future isn't
near. Python still has superior libraries for many use cases, a great
community, easy to learn syntax, and little training requirement (most people
know it or can become proficient in a very short time). Moreover with the type
annotations and linting tools it's becoming a lot easier to write a large and
maintainable Python codebase.

------
cletus
For the record, I like Go. I also like Rust. But I really see them as being
aimed at different markets. Go is a better Python/Java. Rust is a better
C/C++. The interesting thing about Go is Rob Pike envisioned it as a systems
programming language but any language with GC is a complete nonstarter as a
systems programming language.

So as for the author's pretext (writing some tool in Go), personally my view
is "why not?" not "why not Rust?". If someone had written that same tool in
Rust I wouldn't be saying "why not Go?". Whatever floats your boat.

But here is the one part where I disagree with the author:

> Go is unapologetically simple

It is not as simple as it seems, just like every GC language out there. I find
Go advocates in particular seem to dismissive of any GC complexities or
downsides. Maybe because many of them just don't have the background in
dealing with this from years of Java.

I worked on a team at Google that wrote and maintained a project using Go.
Note that I never wrote anything for this project so my experience was second
hand but close second hand.

One thing I remember was the Go binary blowing up on memory limits (10GB+) in
production. Some debugging found there to be millions of Go channels (IIRC)
that needed to be cleaned up. For whatever reason the GC didn't clean them up,
possibly because of a non-obvious dangling reference, possibly not.

Anything can have bugs obviously. It's just a myth that GC is a silver bullet
is my point.

There was a guy who worked on the Go team (David Crawshaw) who'd stop by every
now and again. Occasionally I'd get into debates with him about Go and GC.
It's from these that I established my general observations of Go pundits:

1\. Full GC pauses and GC in general are totally not a problem in Go.

2\. If they were, they're totally going to be fixed in Go 1.N+1 where N = the
current version of Go.

(At the time, the argument David made was that Go's STW GC pauses were sub-
millisecond so totally not a problem).

~~~
zeeboo
The memory leak due to channels not being cleaned up was almost certainly
because goroutines themselves are not garbage collected when they're forever
blocked. In other words, `ch := make(chan int); go func() { ch <\- 1 }()` is a
memory leak. This is analogous to spawning a thread that deadlocks by
attempting to lock a mutex twice, and has nothing to do with garbage
collection.

About the GC pauses, check out the latency graphs at [https://github.com/ixy-
languages/ixy-languages](https://github.com/ixy-languages/ixy-languages)
(being careful not to mix up the Javascript and Go lines). Go handily beat
every other garbage collected language in latency, and is in the same ballpark
as the two non-GC languages (Rust and C). The peak tail latency times are
measured in the hundreds of microseconds even at the highest loads tested, so
I think the pundits may have a point.

~~~
pcwalton
GC is more than just pauses. Throughput matters too; in fact, it often matters
_more_ than latency (for example, when writing batch jobs like compilers).

~~~
zeeboo
Sure, but that's not relevant to the discussion here. In this case the context
was responding to the the statements that Go pundits claim the garbage
collector has low latency but it always has bugs that will be fixed in the
next version. I was providing evidence that the garbage collector actually
does achieve low latency right now.

Also, there are ways to solve your throughput problems if you have control
over your allocations, but there are not ways to solve your latency problems.
Indeed, even if you don't have control of your allocations, you can often run
multiple copies of your program to increase your throughput, but multiple
copies will not help your latency.

Also, tuning your latency does in fact help increase throughput, because if
your process spends a significant amount of time in allocations, its latency
suffers. It's not a zero-sum knob between the two, especially in the presence
of humans that care about tuning the performance of their applications.

~~~
pcwalton
You don't have much control over allocation in Go (in fact, according to the
spec, you have none at all). Language constructs allocate in ways that are not
obvious.

> Also, tuning your latency does in fact help increase throughput, because if
> your process spends a significant amount of time in allocations, its latency
> suffers.

I assume you meant to write "throughput" in that last sentence. That's not how
throughput is defined. Throughput isn't "how long does it take to allocate",
though that influences throughput. It measures how much time is spent in
memory management _in total_ during some workload. Optimizing for latency over
throughput means you are choosing to spend more time in GC.

~~~
azakai
> You don't have much control over allocation in Go

Maybe you mean something different by "control over allocation"? Go does allow
that, for example "The Journey of Go's Garbage Collector" talk has a good
summary,

[https://blog.golang.org/ismmkeynote](https://blog.golang.org/ismmkeynote)

Specifically the sections about value-oriented programming are exactly that:
Go allows the developer to avoid a lot of allocation by embedding structs,
passing interior pointers, etc. Compared to Java or C#, it can have a much
smaller number of allocations as a result.

~~~
pcwalton
> Specifically the sections about value-oriented programming are exactly that:
> Go allows the developer to avoid a lot of allocation by embedding structs,
> passing interior pointers, etc.

To elaborate, for example, indirect calls cause parameters to those calls to
be judged escaping and unconditionally allocated on the heap. Go style
encourages frequent use of interfaces such as io.Reader. So in order to
interoperate with common Go code, such as that of the standard library, you
will be allocating a lot.

> Compared to Java or C#, it can have a much smaller number of allocations as
> a result.

C# also allows you to embed structs within other structs and pass interior
pointers. Java HotSpot has escape analysis as well, though it's less important
for that JVM (and other JVMs), since HotSpot has a generational GC with fast
bump allocation in the nursery.

> [https://blog.golang.org/ismmkeynote](https://blog.golang.org/ismmkeynote)

As I've mentioned before, I also have a problem with the conclusion of this
talk: that generational garbage collection isn't the right thing for Go. The
problem is that nobody has tested generational GC with the biggest practical
benefit of it: bump allocation in the nursery. I'm not surprised that
generational GC is a loss without that benefit.

------
thelazydogsback
I can see moving from C/C++ to Rust for buffer-copying style codes, but for
most code general-use programs the cognitive load required to deal with
resource management seems way to high to move from from Java/C#/Node to Rust.
(I just got called about a shop moving their Node code to Rust, and I can't
imagine why any code that would make good Rust code was written in JS in the
first place.) Go seems like a non-starter to me -- sure features can be abused
(as implementation inheritance has been for years) but to omit generics at
this point just seems silly.

As for moving from C# to Rust, you can learn to program with the Span<> APIs
and get the non-GC perf. of Rust for the most part and still keep GC and other
C# niceties (like the whole toolchain and ecosystem...) in much less time than
a wholesale move to Rust. As as for message-passing/agent/channel programming,
you can certainly do that in C# if you like, and though there is certainly a
lot a foot-shooting that can be done with async and thread contexts, in
general the Task<> system is a joy to use compare to almost anything else out
there, not only for async code, but for concurrent code.

Don't get me wrong, I always thought that C++ was a "worst of all worlds"
language and appreciate moving to Rust from there, but for most user-facing
applications that tend to have complex object lifetimes, I just can't see why
you'd want to deal with RIAA when modern GC's are so darn good.

~~~
dochtman
Have you actually used Rust? I spend very little time (or code) on resource
management when writing Rust code. And when I do, it's usually the compiler
helping me understand an aspect of my design that doesn't work as I expected.
Sure, other languages might allow me to gloss over that, but that will likely
come down to finding the edge case in production.

~~~
rubber_duck
Yes - rust type system is very restricted in what it can express because it
needs to be verifiable at complie time - this means that some trivial things
become a huge pain to describe to rust compiler and rust programmers seem to
develop this Stockholm syndrome relationship with it and start singing it's
praises on every turn. Memory management in dynamic graph structures with
cycles is hard without GC, rust type system is not equipped to deal with this.
Although you can still have leaks by holding on to unused references the
problem becomes a higher level one and describing the structures/managing them
becomes much simpler with a GC.

That guy saying that you can easily avoid GC in C# is also not realistic or
doesn't know what he's talking about - even language expressions can lead to
object allocation in C# - you really need to know what you are doing to avoid
the landmines - it's very clear the language wasn't designed for this - if you
need a lot of code like that.

~~~
thelazydogsback
LOL, I'm "that guy" I think... Glad we agree about the complex/cyclic
structures at least.

Regarding C#, I said _for the most part_. I stick by my assertion that (a) GC
is quite efficient (esp.w/gen0 objects generated by your "expressions") and
far from "lame" and (b) working with value types and Span<> (like Rust Slices)
together can significantly reduce GC pressure to the point where it's
acceptable, assuming there was actually an issue to begin with. Doing this in
C# on hot-paths is certainly much less effort than moving to Rust wholesale,
and you haven't thrown out the GC baby with the bath-water.

All the things that you do to make Rust efficient - allocate on the stack
instead of the heap when you can, pre-allocate when size is known, use
static/nested lifetimes, use slices to owned structures, etc., you _can_ do in
C#, but you don't _have_ to worry about it until it actually becomes an issue.

If you're in the kernel or embedded system or the middle of a game rendering
loop, then sure, Rust's compiler guarantees make this style programming easier
if that's the way you want to go - and Rust has macros and other features that
C# lacks. (Although the .Net JITTer is going to generate type-specialized
methods and inline them, etc., w/a Rust macro you know up-front exactly what
is being generated, which is nice.)

~~~
rubber_duck
My experience in avoiding C# GC comes from XNA era when Microsoft had this
shitty .NET runtime for XBox 360 allowing anyone to develop for it - the GC
was so bad you had to be very very careful to avoid it and stuff like using
foreach would allocate (AFAIK nowdays it can optimize it away in some cases
but not in all and you still need to know when if you want to avoid
allocation). People wrote code which avoided GC but it looked nothing like C#
and in fact was more verbose than something like Rust or C++ and you were in
uncharted territory since no allocation programming is not really C# thing and
using high level features would just lead you into invisible traps. So you
ended up using preallocated arrays, static functions, globals, etc. etc. in a
language with poor generics (you can't even specify an operator as a generic
constraint), no top level functions, etc. etc.

I've kept track of .NET progress since then and read about stuff like Span and
ValueTask, ASP.NET Core team perf did a good job leveraging those for
optimisations (eg. their optimised JSON parser) in such scenarios I agree C#
with low level stuff sprinkled in is a good choice

But if your problem domain requires avoiding GC throughout and having better
understanding on what the abstractions will compile to pick a language thats
designed for that. It's like when I had to review some Java 6 code which tried
to work around the fact that Java doesn't have value types with byte arrays -
it was just soo bad compared to even C equivalent it was better to rewrite and
go trough JNA.

------
Animats
Having used both, I admire Rust as an intellectual exercise, but would write
back-end web stuff in Go.

Go is an OK language, not a great one. The real advantage is that you have the
libraries that Google uses for their own web server side stuff. Those have
been pounded on by billions of transactions, and that the special cases have
been handled. There's one well-tested library for each major web service
related function.

Rust's libraries don't have that volume of use behind them. Look up "http" in
the Rust libraries. You find "Note that this crate is still early on in its
lifecycle so the support libraries that integrate with the http crate are a
work in progress!"[1] (Rust enthusiasts may comment with a complicated excuse
for why this isn't a problem, if they like. That's what the official document
says.)

[1] [https://docs.rs/http/0.1.18/http/](https://docs.rs/http/0.1.18/http/)

~~~
enraged_camel
>>Go is an OK language, not a great one.

This is probably the most succinct and accurate description of Go. It's fairly
decent and reasonably reliable at small/medium scale (which is why it is
popular among the microservices crowd), but has no outstanding features.

IMO by far the biggest reason it became popular is that it is backed by Google
(which makes it a "safe" choice). If it weren't, most people would not have
heard of it today.

~~~
tptacek
"Decent and reasonable at small/medium scale" is a weird way to sum up Go in a
Go vs. Rust discussion, since Go is deployed at drastically larger scales than
Rust is currently. I don't think there's any validity to the idea that Go tops
out at medium-scale projects; in fact, a more common argument against it is
that it makes sacrifices to facilitate large-scale programming that people
don't like.

~~~
steveklabnik
> Go is deployed at drastically larger scales than Rust is currently.

I think it's important to define which "scale" you're talking about here; Go
is deployed at a larger scale in the sense of number of deployments, but both
are deployed in production inside the largest tech companies in the world. For
example, Rust is now at the core of all of AWS Lambda (and Fargate).

That being said, I do think that "decent and reasonable at small/medium scale"
is an attempt at damning through faint praise, and is certainly not how I'd
characterize Go in any sense.

~~~
tptacek
Go is doing more stuff in large-scale deployments, processing more traffic,
doing more transactions, than Rust is. I don't just mean there are a lot more
Go backend projects (there are). I mean that some of those projects do a lot
more work than Rust does right now --- I don't mean ubiquitous infrastructure
things like Docker and k8s, I mean purpose-built components for specific
large-scale applications/platforms.

For instance: "Today, most Dropbox infrastructure is written in Go." Or:
"Today Go is at the heart of CloudFlare's services". Or: "Rend is a high-
performance proxy written in Go with Netflix use cases [ed: all internal
memcache] as the primary driver for development". Or: "The search
infrastructure on [Soundcloud] Next is driven by Elastic Search, but managed
and interfaced with the rest of SoundCloud almost exclusively through Go
services." Or: "How We Built Uber Engineering’s Highest Query per Second
Service Using Go.". Or: "Handling five billion sessions a day – in real time
[at Twitter]".

I don't see where there's room for a "that said" here.

Both languages are obviously capable of scaling.

~~~
steveklabnik
Yeah, as mentioned, I don't think that's true anymore. Historically, it has,
but Rust has had a lot of high-profile, high-traffic deployments in the last
year. But honestly, the high order bit is:

> Both languages are obviously capable of scaling.

This is clearly true, and I agree fully. I don't really want to argue "is this
deployment really larger than that deployment", as it's kind of silly. The
point is that both have demonstrated the ability to scale to the largest
workloads, and so knocking either one of Rust or Go on this axis doesn't make
sense.

~~~
tptacek
I like Firecracker too, more than I like Docker (which is, obviously, Go). I
don't have any problem with Rust. The parent comment, about Go being suited
for small/medium scale programming, was wrong.

------
Communitivity
I have written a command-line log processor in Rust, an XML processor in Go,
and some small microservices in both. My experience in working with both
languages is that Rust has a steeper learning curve than Go, and it took me
longer to feel proficient in Rust. However, once I felt proficient in both I
felt much more productive in Rust.

It's my impression that you may need to have worked with functional languages
and have an understanding of type systems before you can be efficiently
productive in Rust, but for those who reach that I think they can be much more
productive in Rust than Go,based on only my personal experience. One of Rust's
biggest and best features, and its biggest barrier to grokability, is the Rust
Borrow Checker.

I think Go is a very good language, has awesome concurrency designs (I love Go
channels), and is more accessible to more developers, but it also doesn't seem
as flexible. I think the OP hit the nail on the head with the idea that Go is
designed for Enterprise, where a sea or journeyman engineers are working under
a small number of senior eningeers. I think Rust OTOH is designed for senior
engineers, but is usable by less experienced engineers if they are mentored
properly, i.e. 1:1 or at most 1:3.

Also, I like the tooling better in Rust than Go. Rust tools are easier for me
to install, and the cargo build tool is not part of the language, but there is
a standard build tool, so I get to have my cake and eat it too. Meaning I can
customized the build tool to my needs, and have different customizations for
different projects. That can get out of hand, which is why so many hated
Gradle. OTOH, the level of customization is why many shops with senior
engineers loved Gradle (e.g., Netflix).

Examples of build tool install:

* Go: $GO111MODULE=on go get golang.org/x/tools/cmd/stress

* Rust: $cargo install cargo-stress

One thing I think both languages will need to watch out for is the P3 problem
(Package Proliferation Pachyderm), where there becomes an ocean of packages,
some too trivial to really be an effective package (e.g., a package with a
single functor to add two numbers). I've seen this with Node.js, though the
community has noticed it and is working to rectify the situation. This, like
so many problems with language adoption and evolution, is a policy/community
problem and not a technical problem. Both Go and Rust have great communities,
so hopefully we can avoid P3 in the future.

~~~
agumonkey
I have zero field experience regarding go, but it seems to me that it's made
to remove friction for teams.

Lean toolchain, lean build times, lean formatting (can you imagine the amount
of time wasted on IDE config, commit syntax, and formatting style debates ?)
so that large groups can just go to work.

ps: I'd love to work in rust. As you said, it seems very potent at making very
expressive yet very efficient code.

~~~
hinkley
I was trying to do some CLI formatting this weekend and discovered that an
equivalent to leftpad exists in the Node API.

I was up to my elbows in troubleshooting (when you don't know how to solve the
problem, describe it more clearly), so I didn't have time to dig into the
history, but I got a chuckle out of that.

------
darklion
> Go is a better Java / C#, while Rust is not.

Mm, not really. Go is a less sophisticated Java / C#, in the same way that a
bicycle is a less sophisticated motorcycle. There's situations to use both,
and there's nothing with either, but sometimes you want or need to travel
hundreds of kilometers in a day and a bicycle isn't going to cut that for most
people.

~~~
DocSavage
I hate bad analogies that have us arguing more about how well the analogy fits
than simply debating the underlying question. When we talk about concurrency
or the ability to make simple yet high-performing server apps, it's ridiculous
to say Go is a bicycle compared to the motorcycle that is Java / C#.

User-space network driver? The benchmarks group Go closer to Rust with Java /
C# way behind: [https://github.com/ixy-languages/ixy-
languages](https://github.com/ixy-languages/ixy-languages)

This would be a very complex comparison and simple analogies do us a
disservice. I think the author's blanket statement that Go is faster than Java
/ C# also seems too broad.

~~~
loonyphoenix
How do you get that C# is way behind Go on this one? If anything, those
benchmarks show these groups of languages performing at roughly the same
level:

1\. C/Rust

2\. Go/C#

3\. Java/OCaml/Haskell

4\. JavaScript/Swift

5\. Python

~~~
DocSavage
I agree that my wording is too strong due to my memory of the latency results.
As you increase the load, Go is closer to Rust/C than C# (see last benchmarks)
and at a given load, C# isn’t in picture. It’s fair to say that Go/C# is
similar while Java is far behind depending on the benchmarks that are
important to you.

~~~
joelfolksy
> and at a given load, C# isn’t in picture

And depending on how you draw the picture, Go might not even be in the
bandwidth picture.

------
maxpert
Fortunately I've used Go, Kotlin and C# in production building systems dealing
millions of rpm. I can correlate my experience with different parts author has
described. But I would disagree with few parts, specially simplicity part. You
see the so called "simplicity" comes at a cost of extra verbosity and pain
e.g. no generics; I have to add 3 extra lines of code, and repeatedly do
casting and `ok` checks to just get value out of an in-memory LRU cache. Now
some of folks might argue well this is the right way to do it. IMHO generics
is one example of compiler slacking on me, and putting the burden on developer
to maintain those extra lines of code. I do agree with C#'s breakable TPL
model where you can choke threads; and I think that problem exists due to
Tasks being slapped on to legacy down the road. If they were to reinvent
another language I bet no-body with sane ideas will ignore the async
programming model. Kotlin is one such example.

I can keep going on and on, but to cut it short; yes I would write a high
performance router, reverse proxy, or a very simple micro-service in Go. But I
would never recommend anyone to write a high business complexity service in
Go. It's a matter of time before somebody writes a transpiler that would take
these short comings of Go, and fixes them (Like Kotlin, Nim etc.).

~~~
kristoff_it
I'm honestly conflicted about generics. I see your point, and I have felt the
need for them in the past. My main concern is that as of now the lacks of
generics forces people to rethink a little their approach to development,
while with generics I fear there will be a proliferation of not-always-great
patterns that will be copypasted from equivalent Java/C# code.

The Go community has a lot of good ideas on designing interaction through
interfaces that I really hope won't get lost in Go 2.

That said, yes, casting interface{} manually over and over is stupid, let's
hope we can get the best of both worlds.

------
kitd
I've moved from Java to Go and I appreciate it very much. It's very practical
for day-to-day development. The 2 killer features for me are:

1\. the built-in tooling (cross-platform building, profiling, formatting, test
coverage, etc)

2\. the standard library. I've written services that have convoluted TLS
certificate handling, encryption and REST calls and never had to look
elsewhere.

The language itself is good, though 2 gripes for me:

1\. _x.Y_. At first glance, it isn't obvious whether this is function Y in
package x, or method Y on object x. Package::function would be better IMHO.

2\. The ':=' assignment with inference operator has sometimes led to
unintended variable shadowing.

edit: another one comes to mind. The usual ... generics, pretty pls?

BTW, the author claims Go is faster than Java. Is this true, because it didn't
used to be?

~~~
LandR
> BTW, the author claims Go is faster than Java. Is this true, because it
> didn't used to be?

I think for certain use cases C# or Java will be faster. THere was a post here
the other day about a network driver written in C, Rust, C#, Go, Java and a
few others and The C# one was faster then Go. Can't remember if Java was
faster or not.

~~~
coder543
> The C# one was faster then Go

As pointed out over here
([https://news.ycombinator.com/item?id=20984503](https://news.ycombinator.com/item?id=20984503)),
Compared to C#, Go was faster (higher throughput) for smaller batch sizes, and
it _always_ had significantly lower latency.

.NET Core is particularly good these days, so I'm sure there are times when C#
is definitely faster than Go, but the network driver isn't a great example to
support that.

~~~
joelfolksy
Are we looking at the same charts? Go and C# are practically on top of each
other for smaller batch sizes, then C# pulls ahead significantly.

~~~
coder543
If you’re looking at the latency chart, higher is worse. The right hand side
of the C# graph is not a good thing.

The throughput graph doesn’t show C# pulling ahead significantly. Significant
is how far behind Java is from Go and C# in that benchmark.

Also be sure you’re not looking at JavaScript on the throughout graph, since
it is colored very similarly to Go.

------
tomashubelbauer
I tend to agree with the message in the article, even as someone who's in the
past been a bit overzealous about evangelising Rust. The most striking point
to me though was the one about not using tribalistic names like Rustaceans and
Gophers. These never sat well with me because they sound silly, but I also see
how they could be inadvertently reinforcing silloing across programming
languages.

~~~
seren
I agree and it echoes what Paul Graham said here [0] about ego.

If your identity is tied to being a 'Xer' you are going to have a hard time
working with 'Y' even if it is the best solution in this case.

Don't identify as a Xer or Yer, but as someone solving problems and creating
value.

[0]
[http://www.paulgraham.com/identity.html](http://www.paulgraham.com/identity.html)

------
epx
Rust is lower-level, it is a replacement for C and C++. I'd love to work with
Rust but there are only so much low-level projects where it makes sense -
kernels, Web engines, things like HTTP servers. Go covers those cases where
you would like to use Python but it would be too slow.

~~~
k__
Would be cool if Rust could cover that gap.

~~~
AstralStorm
It's close enough with its syntactic sugar and type system. There's no gap at
all, really.

One place where Java and C# win, and sometimes C++, is the availability of
excellent libraries. Rust doesn't have as many and not as fleshed out either.
Go has the same problem though.

~~~
asdkhadsj
Agreed, I write everything in Rust these days. I usually dogfood areas where
normally I would recommend Go but I'm curious on what the end product will end
like in Rust. So far, all the projects have been super easy and only as
complex as I want them; with one exception:

Diesel. If a developer came to me and wanted to write something in Rust over
Go, but didn't know Rust well and wanted to use Diesel, I'd warn them not to.
The errors you can get from Diesel are insanely unhelpful and quite advanced
in the type system.

With that said, I don't think Go really has a comparison to Diesel either.. so
perhaps this is an unfair warning. If instead you use raw SQL with Diesel,
suddenly it becomes just as friendly as Go's SQLX, and yet again Rust becomes
largely as simple as Go.

Rust is in my view surprisingly simple. If you choose advanced features you
usually understand them. It seems to me that using libraries are the biggest
threat to making Rust feel insanely complex; ie Diesel's type system.

As an aside, I hope one day Diesel can achieve errors akin to TQL (which I
found recently), as TQL really nails the error reporting from what I've seen,
at least.

~~~
hathawsh
I'm having a similar experience with Rust. Libraries that expose complex types
can be hard to use because mistakes lead to confusing compiler error messages
with over 100 lines of mostly irrelevant details. I can use libraries that
expose complex types, but I have to be prepared for a steep learning curve for
each such library. On the other hand, there are many libraries that expose
only simple types and I can use them easily.

BTW, I love how the Rust compiler uses all CPU threads. It's fast on my 8 year
old Ubuntu desktop with 6 cores / 12 hyperthreads.

------
jonathanstrange
I agree with the author that some Rust zealots are overdoing it and don't do
their community a huge favour, they were one among several reasons why I chose
Go instead of Rust for a larger project I'm working on. It's especially
annoying to talk to the fanatics when you know Ada fairly well. (Most of them
seem to come primarily from C++...?)

Like the article suggests and was stated numerous times, Rust and Go are not
competing languages, they have different use cases. Rust is a good choice if
you want to write a rock solid and secure library to replace a C++ library, or
instead of writing it in C++ in first place. Go is a good language if you want
to write a web service and want to rely on many existing libraries to cut down
development time.

Both are great languages if you know them intimately as an expert and are
deeply familiar with the common frameworks. Almost every language is great in
that case.

However, for my use cases Rust would be a bad choice. Relying on GC is not
only perfectly fine for my performance requirements, it also makes life much
easier.

Personally, I think that both Rust and Go are a step back when we're talking
about pure language features. They are both needlessly and artificially
restrictive in comparison to good old languages like Ada and CL. But in the
end, the frameworks and 3rd party libraries are more important anyway.

------
_bxg1
I was having a conversation the other day with a principle JavaScript engineer
who's been in the industry for 20 years. I asked him, "What's the use-case for
Node in industry? It's so much slower than other server platforms, which in
the age of the cloud translates directly to real expense. Is it only used by
startups who need maximum agility?"

His answer was that for larger companies, server costs are orders of magnitude
cheaper than payroll. It's often much more valuable for a company to improve
their development process than server performance. So high-productivity (and
ease of hiring) technologies like Node and Go can end up being a really good
business tradeoff in terms of actual dollars, even if they result in double or
triple the server costs.

------
leshow
> Go is faster than Java / C#, more memory-efficient than Java / C#, and
> definitely has better concurrency than Java / C#

C# is a great language and has a ton of modern features. It's also quite a bit
faster than the author is giving it credit for. In fact there was a network
stack written in it that was posted here last week that had it beating Go by
an order of magnitude.

I don't really agree with the statement that 'Rust is a better C++' either. It
very much can take the place of C in many applications also.

~~~
patrec
What features does Rust have that C++ lacks that allows it to be used as a C
replacement when C++ can't be?

~~~
eximius
Memory safety?

C++ has lots of bells and whistles, some of which Rust doesn't have (classes,
to name one), but those aren't necessarily more important bells and whistles.

Also, the Rust infrastructure is light-years ahead of linking in libraries in
C/C++. Compile times are higher, but not horribly so.

~~~
jcranmer
> Also, the Rust infrastructure is light-years ahead of linking in libraries
> in C/C++. Compile times are higher, but not horribly so.

Sorry, but you've got this backwards. From a user's perspective, cargo seems
like a much nicer build system than the more-or-less manual build systems of
make et al. But that's because cargo is opinionated and inflexible: it really
wants to be the primary driver of the build system, and it also doesn't quite
support all of the things you can do with custom linking.

As a result, when you have large projects composed of multiple libraries, your
choices are either to drive rustc manually and skip cargo altogether, or to
create a single macro crate for cargo to link all the rust code as a
sublibrary for linking into your main project code. You end up with something
like this: [https://dxr.mozilla.org/mozilla-
central/source/toolkit/libra...](https://dxr.mozilla.org/mozilla-
central/source/toolkit/library/rust/shared/Cargo.toml) to describe all of the
Rust libraries you have in your project.

~~~
eximius
... is that bad?

Seems different. But it doesn't seem bad.

Granted, I've not worked on a project of that size, but it seems to me that if
it works for 'normal' sized projects quite well and works as well as anything
else for large projects (as in, nothing works perfectly for large projects,
they all need tweaking), then it is ahead of the alternatives.

~~~
jcranmer
What it shows is that Rust's aggressive approach to static linking means that
it doesn't slot into build systems the same way that C/C++ code does. This has
benefits for smaller projects, but it probably discourages use in larger
projects.

I don't know what all of the trade-offs are, so I don't know where the current
situation sits in this space.
[https://gist.github.com/rylev/0e3c3895dcb40b6a1c1cf8c427c01b...](https://gist.github.com/rylev/0e3c3895dcb40b6a1c1cf8c427c01b5e)
is the minutes of a session between the scary-custom-build-system people
discussing (among other things) the pain points of cargo with their build
systems.

------
codeisawesome
I feel this article so hard on so many levels. I've experienced Dante's
Enterprise.

BUT, regarding what I feel to be a false equivalency - Is Go truly right for
the _exact_ kind of Enterprise Mush that the Author is describing? Go was
invented at Google to solve Google problems is the claim in TFA. And yet,
Google is famous for having a very high bar for engineering hiring with a
strong focus on CS prowess.

So, is the kind of code mush that gets created at Enterprises who put
production code written by one-week-of-pluralsight Junior devs headed by
analyst-preached-cargo-culting managers - the same as - the Software produced
at Google? If not, does Go still fit that former zeitgeist?

~~~
kristoff_it
Hello fellow lost soul.

I don't ultimately know, I think some enterprises are doomed to fail
regardless of the technology they end up choosing.

In some ways their inevitable doom is capitalism's greatest gift to society,
but I've worked in a shop where we had both Go and C# at the same time, and I
would have quit way earlier if I had to work on the C# code full-time. Both
green-field projects btw.

------
JulianMorrison
Go's hidden feature is that there are no personal dialects of Go, not even in
the whitespace, because everyone uses "go fmt".

As such, you look at it, you see what it's doing, not how clever the
programmer was. And you can feel free to dive in and edit.

~~~
skohan
I haven't written a ton of go, but my read on the language is that it's built
for large teams with lots of turnover. It makes it really easy to write
boring, readable code and it makes it really hard to write code which is too
clever by half.

If I am choosing a language for a personal project, or for a small team of
developers I'm really confident in, I'm probably going to choose something
which is more fun to write. But if I had to recommend a tool for a large shop
where long-term maintainability regardless of the team makeup is more
important than programmer happiness, Go seems like a great option.

~~~
JulianMorrison
And yet Go programmers are often happy.

I think the reason is: Go code has a low level of abstraction-construction and
a high level of explicitly writing the algorithm. You can see _through_ the
language, which is "boring" and does not distract your attention, to what it
is trying to achieve, which is interesting.

~~~
ummonk
Yes, I agree with this, but need to caveat it. Go is a fun language to write
code in (it has the simplicity and directness of C, which is also a fun
language to write code in, while avoiding the warts of C). Like C, it isn’t a
fun language to rapidly develop features in, because it is very boilerplatey
due to limited abstraction.

Incidentally, for this reason I’ve always enjoyed coding in C because in
domains where I’ve used it (most embedded code) the required feature set is
quite limited, so C’s slow pace of development isn’t a problem. On the other
hand when working with Go server code at a startup, I was deeply frustrated
because I just wanted a much more abstract language to rapidly write features
in.

------
illuminati1911
”While the story above is 100% the result of my imagination, it’s no secret
that the Rust fandom has a few overexcited members who feel compelled to
enlighten every lost soul about the virtues of the Crab-God.”

Just like any programming language and probably most of all Go. The fanaticism
around it is just next level.

~~~
blub
I can't think of any other programming language discussed on HN besides Rust
where hordes of people will doggedly praise it and nitpick any criticism of it
to death. Maybe Haskell, although even that doesn't compare.

Every mention of Rust on HN feels like a public relations exercise where one
is force fed an opinion until they learn to like it.

The Go community's actually quite relaxed, all things considered, which makes
them look more self-confident and less desperate.

~~~
illuminati1911
Was this supposed to be sarcasm?

I have actually never seen anything like what you mentioned when it comes to
Rust. I think I have actually lost ~50-70 karma here on HN for constructively
calling out some flaws and things I don't like about Go. Hasn't happened with
any other languages though.

I think the cult mentality with Go is a special kind.

Btw. I'm Go developer myself and I do like the language, but I just don't get
the "jihadist" attitude that seems to be far too common here on HN.

------
hyperpape
A minor nit about this article:

> Go has great concurrency support, but Rust has provably-correct concurrency.

I believe it's incorrect to say Rust has provably-correct concurrency. It
prevents data-races, but not race conditions: [https://doc.rust-
lang.org/nomicon/races.html](https://doc.rust-lang.org/nomicon/races.html).

------
hydandata
I love Common Lisp, which is definitely on the other end of the spectrum, but
still enjoy Go a lot too.

For me it is a perfect fit for writing automation, services and command line
tools. It is stable, it is simple to use/write/read, it is easy to deploy, it
has great IDE support and tooling, it just _makes sense_ in the enterprise, as
author himself notes.

I like Rust too, but compared to Go it has the feel of a research project. I
think Rust has great future, I definitely see using it, but for now I will
stick with CL/TS/Go.

~~~
tombert
Out of curiosity, do you use Common Lisp for work or just for fun? I get to do
Clojure about half-time (it was an easy sell due to a lot of our stack being
Java), and really like it, but haven't used Common Lisp at all.

If you do get to use it for work, how does it scale (programmer/code-wise, not
efficiency-wise) for "real" projects?

~~~
hydandata
I used it at work[0] for a few years and it was great, but I did not scale
that project to large number of people, mainly because it did not need to.

Folks at Grammarly have a writeup about how they are using it, it might have
more relevant information for you[1].

I would definitely consider using it again, but proper buy-in takes time, and
I have simply been moving too fast since then.

I am still not a big fan of Clojure myself, but it is definitely seems easier
to sell than CL. In my humble opinion, if you are already a convert the
benefits of going from Clojure to CL will not be as great as the ones for
going from Java to Clojure.

[0]
[https://news.ycombinator.com/item?id=13979002](https://news.ycombinator.com/item?id=13979002)

[1] [http://tech.grammarly.com/blog/posts/Running-Lisp-in-
Product...](http://tech.grammarly.com/blog/posts/Running-Lisp-in-
Production.html)

~~~
tombert
I actually went Haskell->F#->Clojure in terms of job progression, so I am ok
with largely theoretical stuff.

The reason I ask is that Clojure is an easy-ish sell largely because there's a
near guarantee that you will never be blocked due to lack of libraries, since
you can mooch off of anything in the Java ecosystem (similar arguments can be
made for F#). I hate Java, but it has been around a long time and is extremely
popular, and as a result there is a library for virtually anything for it. As
far as I know, there is no such guarantee for CL...unless I'm mistaken (which
wouldn't surprise me).

When using it for work, did you ever get stuck because of a lack of libraries
(e.g. JSON parsing, protobufs, socketing stuff, threadsafe collections)?

~~~
hydandata
> When using it for work, did you ever get stuck because of a lack of
> libraries..?

Nope, I did find some to be less well documented than ideal, but pretty much
everything had tests and/or examples making up for it. Have a look at
Quicklisp[0] and explore yourself.

CL has many implementations[1], including the one targeting the JVM, so you
can make use of Java ecosystem from it too.

CL has been around a long, long time. First edition of CLTL[2] was released in
1984! and at that point Lisp had already been in heavy use for almost three
decades. The standard has not been altered since 1994, and likely never will,
but due to its nature innovation continues in the individual implementations
and in the community, and there is a well established culture of portability
libraries.

[0] [https://www.quicklisp.org/beta/](https://www.quicklisp.org/beta/)

[1] [https://common-lisp.net/implementations](https://common-
lisp.net/implementations) \- Not an exhaustive list

[2]
[https://en.wikipedia.org/wiki/Common_Lisp_the_Language](https://en.wikipedia.org/wiki/Common_Lisp_the_Language)

------
krn
I would choose Go to solve network I/O bound problems, Rust to solve CPU /
memory bound problems, and Clojure to solve business bound problems: where
mental cycles are more expensive than computational cycles.

------
gameswithgo
From the article: "Go is faster than Java / C#"

The is more often untrue, than it is true. There are times when the low
latency GC is beneficial though.

~~~
electrograv
That’s right, and this is confirmed by many benchmarks I’ve seen. I agree with
pretty much everything in this article except the repeated claim that “Go is
fast”.

Of course “fast” is relative, but I would reserve it for languages that are
nearly as fast as competitors in their segment. There are too many languages
very similar to Go’s ergonomics that are much faster for us to meaningfully
call Go “fast”.

That said, I don’t really think that’s a problem. I think people who use Go
are often just happy it’s faster than Python, and that’s okay.

My personal dislike of Go comes simply from their unapologetic[1] embrace of
default nullable pointers (the “billion dollar mistake”[2]): There is very
strong theoretical (and practical) ground supporting the approach of
Rust/Zig/Swift/etc’s (to use algebraic data types instead) as _objectively
better_ (yielding inherently more reliable results with virtually no ergonomic
compromise[3]).

In other words, in the 21st century, we know how to design statically typed
languages that _guarantee_ the impossibility of null dereference exceptions
(not counting bugs in external libraries from other languages). And we can do
this without any runtime performance or code ergonomics compromise!

Therefore there are _no_ good excuses anymore for any statically typed
language in the 21st century to _not_ provide this extremely beneficial
guarantee.

[1] There are no plans to fix this, ever: I’ve seen entire articles written by
members of the Go team not just defending “all pointers are nillable”, but
_encouraging_ this as an idiomatic Go style of coding.

[2] [https://www.infoq.com/presentations/Null-References-The-
Bill...](https://www.infoq.com/presentations/Null-References-The-Billion-
Dollar-Mistake-Tony-Hoare/)

[3] The ergonomic difficulties of Rust come from the borrow checker, not from
their use of algebraic data types to replace nullable pointers.

~~~
steveklabnik
Has there been a statically typed language with no null _and_ no generics? I'm
pretty sure that every language I've used that implements an Option-like type
has it be generic. Maybe TypeScript, where you can have "number | null"?

~~~
kristoff_it
Go is already getting away with a magic generic map type, they could have done
it the same way, it they wanted to.

------
yitchelle
"Well, you could answer that Go is what you know, so that’s what you used to
solve your problem,"

This is definitely an appropriate answer for the author to give. He wrote a
small tool, and most folks writing a small tool would just run with what is
already know by coder.

~~~
tom_mellior
Yeah. The whole premise of the article is "if someone trolls you, feed the
troll".

------
acje
I come from a network background where it is common to separate data plane
(speed) from control plane (complexity). I think Rust and Go can fill one of
these niches each.

Because I wanted speed, Rust became my choice. But that zero cost abstraction,
does not extend to the programmer. The cost is in the productivity. Although
productivity in Rust is likely better than most older languages, C in
particular.

I also like Starlark, very weak language in terms of features. That is its
strength imho.

For the sake of context. Rust is my eleventh language, but I haven’t written
much software, and most of it was ten years ago.

~~~
steveklabnik
We've even seen this in shipping products; Linkerd 2 is exactly that: data
plane in Rust, control plane in Go.

------
Spiritus
Maybe just me, but I feel this thread is just validating everything he’s
saying. Literally every comment is an explanation/excuse why you should use
Rust or why Rust is better at literally everything.

Disclaimer: I’ve had a “few” beers so I might talking with my ass, but damn...

~~~
steeve
Every article about Go you can CTRL-F "rust"

------
davesque
Honestly I'm a bit confused why these languages are constantly pitted against
each other as though one has to eventually win out. They were each designed
with different goals in mind and suit different tasks.

------
spion
A good answer is: if you can afford it (and you often easily can for server
side code), GC is a no-brainer as it offers memory safety, ease of use and
very good performance all at the same time.

------
sudeepj
Go is simple & simplicity scales when it comes to development (learnability,
dev-effort, tooling, etc). So from a manager's point-of-view he/she can
hire/train people far more quickly with Go than Rust. As much as I love Rust
and have advocated for it in my company I cannot argue on this point with my
management.

------
Yoric
As a devoted and long-time Rust user, I'll tell you: by all means, use the
language in which you're most comfortable and/or which seems best suited for
the task!

Rust is not meant to replace every single language on Earth. Rust is, as you
mention, a better C++, with great predictability, great safety and great
concurrency. That's a feature set that's critical for some classes of
applications, but absolutely secondary for others.

It's a good thing we have more than one language to pick from :)

------
notus
I think they have different applications. If I were to choose a language for
writing a web service I'd use Go but if I wanted to write an opengl renderer
I'd use Rust.

~~~
CalChris
Memory safety is Rust's hallmark. Is memory safety such a concern with opengl
renderers?

~~~
jerf
Graphics code has a _long_ history of memory unsafety, in more recent years
causing serious security issues when we tried to put OpenGL on the web with
WebGL, resulting in every device driver bug turning into a kernel-level
vulnerability in the JS code. You've got a lot of people writing code with
more brains than discipline [1], writing in an environment where performance
is priorities one, two, and three, writing in memory unsafe languages... yeah,
memory unsafety in rendering code been a big problem for a long time.

[1]: One of the most dangerous types of coder there is is the brilliant one,
who has several times the working memory capacity of a normal person, and who
can write 1000-line "functions" without breaking a sweat, and builds entire
codebases out of such things. (Sometimes, perhaps the core loop of a program
will be a bit of a monster, but the whole program isn't like that.) The cost
of salvaging such things can be disturbingly close to the cost of rewriting
such things, and indeed, the process for either may not be all that different.

~~~
PyroLagus
Also, even disregarding security issues. Maybe you just don't want your video
game to crash during a boss fight? Memory safety isn't just important for
security; it can also prevent lots of annoying bugs.

------
jillesvangurp
Knowing very little about go, I jumped in to do some maintenance on a few go
projects two weeks ago. I was able to do what needed doing within a few hours
and implement a few simple changes. I did not consult any books or tutorials.
But simply learned by example and did a few targeted searches to figure out
basic stuff like "how do I assign a value to a variable", "what syntax do I
need to use to create a struct". Mostly, it's all fairly straightforward.

The code base has a history of non go programmers doing work on it. It's not
pretty but it works and is maintainable. IMHO that is impressive. I'm sure a
few senior go developers would be all over the code base to improve it. But as
it is; it kind of does what it is supposed to without much fuss. Having looked
at but not really used Rust, I'm pretty sure there's no way I can be
productive in that language on a similar timeline. Unreadable rust is a thing
if you are not familiar with all it's syntax, macros, type voodoo, and pointer
juggling.

That being said, go does look kind of ugly and verbose too me. I've never seen
so many "if err != nil" statements before. The code I was working on is
littered with it. Error handling is going on all over the place along with a
lot of conditional logic around that which is a bit of a code smell. I also
noticed a poor man's version of OO where you have structs and then a bunch of
functions operating on that struct as the first parameter. I think I'd prefer
the real thing. It seems variables are mutable by default, which seems a bit
backward these days. So, there's also a lot not to like.

------
tombert
> There are only two levels of visibility for variables, and the only
> concurrency model is CSP.

I think this is generally true, but in the interest of pedantry, I feel like I
have to point out that Go _does_ have "traditional" locks and mutexes and
whatnot, if you're feeling masochistic and don't want to use channels for some
reason [0].

[0] : [https://gobyexample.com/mutexes](https://gobyexample.com/mutexes)

------
perspective1
Love these points. They answer "which language is better for building
enterprise services in the vast majority of cases." Go, is simply good enough
and makes well-thought out compromises for "non"-zero cost abstractions.

For me, I'm a part-time solo "services" developer using Rust. I've built some
terrible projects that I hate peeking into to add features and maintain. But,
ultimately that's gotten better and the web-services story is maturing (Actix
is somewhat unstable but easy to work with, and async/await will finally hit
stable in a few months). I also write non-idiomatic code quasi-functional code
that works for me but others would scoff at or at least find hard to maintain.
Rust, to me, is an enjoyable language to use and has great tooling (debugging
being a major exception). I've become productive in it after a heavy upfront
cost. And, although I haven't quantified this exactly, its speed saves me
money considering my relatively small single server.

I think, as a sole-developer, the largest issue with using Rust for services
is the package support. Python, Go and JS all have mature Redis packages, for
instance. Rust's works, but it has some peculiarities particularly with
connection management and some Redis commands. It's enough where I could get
everything working with enough time. But I don't have all the time in the
world. It's a similar story for lots of packages, even in Actix web. You often
have to dig into the source code to figure things out. I'm trialing a
"microservice"-like architecture solely because it's easier to do some things
in other languages. Hopefully widespread WASM support hits soon but I'm a
long-time single-server guy now trying to figure out Kubernetes because I find
Rust enjoyable.

~~~
kristoff_it
Well maybe the Redis packages problem can be solved, I started working on one
for Zig [1], maybe I'll bite the bullet in the future and contribute to redis-
rs too :)

[1] [https://github.com/kristoff-it/zig-heyredis](https://github.com/kristoff-
it/zig-heyredis) (far from complete)

------
shmerl
To summarize the answer, Go was created as a better replacement for Java and
other managed languages. Rust was created as a better replacement for systems
programming languages (the author brings this point in the conclusion).

This claim however is somewhat misleading: "Rust is a C++, not a C". It's
clearly not either of them - it's a new language. However, it's a good
replacement for both C and C++. May be the above idea means, that those
familiar with C++ concepts can find Rust easier to understand - that's true,
it uses major ideas from it like scope based resource management (aka RAII)
and so on. But it uses other ideas as well.

No language is perfect in absolute sense, and each has its own trade offs. But
the above gives a rough framework to answer "why Go and not Rust" or "why Rust
and not Go" in some particular situation.

There is always going to be some overlap area, where both are adequate enough,
so any answer to such questions would be moot there.

~~~
kristoff_it
This comment on Reddit I think explains why I think there is a big difference
between C and C++ and why in my opinion Rust is not the best substitute for
the former:

[https://old.reddit.com/r/programming/comments/d50u9g/why_go_...](https://old.reddit.com/r/programming/comments/d50u9g/why_go_and_not_rust/f0j5na2/)

~~~
shmerl
I agree with the view of "portable assembly", or to say it more correctly,
language that allows high level of control. Rust at least aims at that, so it
should be a good replacement for C.

Some things were still missing though, if I remember correctly something like
handling memory allocation errors was an issue, which is important for
embedded systems and similar scenarios. I suppose there was some plan to
address that.

------
akavi
Tangentially, what language right now most closely hits the mark of Rust + GC?

I'm thinking Algol based syntax, expressive type system (sum
types/generics/structurally typed structs), and optional mutability like Rust,
but without the mental overhead of memory management.

~~~
stefano
Swift. Automatic reference counting still requires more developer attention
(to break reference cycles) than a GC, but is still easy to get right. Too bad
that outside of iOS development it's still unusable.

~~~
skohan
I agree with this assessment. Swift has a lot of the things that make Rust
nice to work with, but favors usability over performance while Rust does the
reverse.

> Too bad that outside of iOS development it's still unusable.

Sub-optimal for sure, but not unusable. It's being used in production on the
server in several instances.

------
surfsvammel
I’ve written a bit of Go and am learning Rust. In my toolbox I believe there
will be a place for both.

------
IMTDb
> Well, you could answer that Go is what you know, so that’s what you used to
> solve your problem, but that’s probably not going to be a satisfactory
> answer.

It should be

~~~
AdamJacobMuller
It is, for sure.

As long as the tool gets the job done, I don't see the issue.

That's not to say some tools aren't better suited to a task than others, or
that there isn't room for improvement, but, unless things are manifestly
mismatched I don't see why it wouldn't be a satisfactory answer, especially
for a "hey i wrote this cool thing" project.

------
deg4uss3r
Contrary to popular belief there is _not_ one ring to rule them all.

------
tomohawk
As an experienced Java dev, I switched to golang for a few years and really
liked it. Recently, I find myself on a "enterprise" job with Java. I really
miss golang.

Boxed types? What a crazy idea that an int can be null. Just fixed a bunch of
bugs related to that. String can be null? Just say no. golang's value types
are much less error prone. You can go out of your way and pass a pointer to a
string, but having to always worry about whether something is null in Java is
a PITA.

The concurrency story in Java is also horrible. So much effort is required to
achieve simple things. You're always having to make trade offs with the heavy
weight threading model. Thread pools? What is this, the 90s?

With golang, I never once messed with the gc. Not once. We have a gc related
discussion about once a week with Java.

And the deployment story. So simple with golang. So much extra work for
nothing with Java. Just give me an executable I can run. How hard is that?

------
rcarmo
The "enterprise software" bit is a drum I've been banging on for a bit, and
which always gets me into trouble from Java/.NET/OOP advocates who usually
sail under the "legacy modernisation" flag when they point out that dependency
management in Go is sub-optimal in closed environments.

But I think it will get there, eventually.

------
semitext
While I don’t think it should be the only consideration when deciding on a
language to use, I think there is something to the idea that you should use a
language that makes you happy. I know a lot of people that use Go that really
like using it.

------
worik
AFAICT This is a "GO is great" article not "GO Vs. Rust" article as the title
suggests.

It is OK to love and propmote a language. GO is terrific and we have been
waiting for it for a long time.

But so is Rust.

If you want to say GO is better choice than Rust ("Why GO and not Rust" is the
title after all) listing featurs of Rust ("...Go doesn’t want unused variables
or imports...") is not a convincing way to proceed.

Horses for courses and we should have stopped language wars in 1995!

------
w8rbt
I like to think that Go is C for the Cloud.

And don't let detractors get you down. No matter what you do, or how
successful you are, there will always be critics. Ignore them.

------
apta
> Go was created at Google to solve Google problems

Still, the vast majority of critical and infrastructure code at Google remains
written in C++ and Java. Languages with superior performance, ecosystems, and
that have actually proven to work in large scale programming (as opposed to
hand wavy incorrect claims about being that).

golang is more or less a hobby project with a lot of bad design decisions that
went too far.

------
alexnewman
I like them both but honestly if you don't know which one to use for your
task, you probably don't know them both well enough.

------
ancarda
Because the Go standard library is nice - net/http is a joy to use

------
zbraniecki
I'm not discounting your experience, nor am I trying to devaluate the problem,
but I think there are more than one reason why someone may ask "Why not
Rust?".

In my case, I sometimes ask it to learn about particular real or perceived
shortcomings of Rust, which may be fixable.

If I believe that Rust should address the problem, and someone chose not to
use Rust (which is different from choosing to use Go!) I am curious as to what
obstacle the person hit.

We should tame the zealous members of our community, but don't cluster
everyone into the same bucket :) Some of us are just trying to build a great
ecosystem and that requires us to find blindspots and notice hard-to-observe-
from-inside problems.

~~~
kristoff_it
> I think there are more than one reason why someone may ask "Why not Rust?"

Strongly agree, that's how I concluded the blog post :)

------
streetcat1
Go was designed by ken Tompson. Arguably the best programmer alive.

------
jaichabria
There is a lot of why go in the article, but not much about why not rust. I
couldn't tell why the conclusion was that Go is better than Rust at certain
things.

~~~
std_throwaway
"The devils you know vs. the devils you don't." It's been keeping C alive for
decades. Now go is an old boy, too. Rust is the new kid that seasoned
developers don't trust. It's got not enough features and yet too many already.

------
kumarvvr
I always thought rust was for system level stuff, like writing a database
engine and go was for more backend server jobs, like distributed
processing,etc.

------
qaq
Try creating a type in Go to represent arbitrary JSON.

~~~
sacado2
interface{}

~~~
qaq
very safe option

~~~
dullgiulio
It's 100% memory safe. In other languages you would use the same (some
variation of Object.)

------
norswap
Why are people upvoting this religious language war drivel? The arguments
aren't even good. Heck, they aren't even _substantiated_ , not even badly.

I'd like to offer constructive criticism, but really, there is nothing to
salvage here.

\- Go is much easier to learn than Java or C#.

\- The Go community regards as anti-patterns many abstractions regularly
employed by Java / C#.

\- With Go, it’s easier as a junior developer to be more productive, and
harder as a mid-level developer to introduce brittle abstractions that will
cause problems down the line.

Huge red flags all.

------
Myrmornis
I haven't used go much yet but I can say that the O'Reilly book on Rust is a
really enjoyable educational experience.

------
maximp
I love this. I haven't found many articles comparing and contrasting languages
this way, and I really appreciate it.

------
kod
"Rust is a better C++"

Rust is very clearly an ML derivative, not (just) a better C++

------
bullen
Can you share memory between cores with go without copying the memory?

~~~
scottlamb
> Can you share memory between cores with go without copying the memory?

Yes. Go's "do not communicate by sharing memory; instead, share memory by
communicating" thing [1] is advice, not a language requirement. Go's memory
model is similar to C's. Channels are completely optional; you can share
pointers and protect stuff with mutexes. You can skip the mutexes and have
data races, too, unfortunately. At least Go has good tooling for finding these
kinds of races dynamically. [2]

Rust is similar, except that it prevents data races (as well as other types of
memory errors) in safe Rust code, barring compiler bugs. I absolutely love
this property, and it can save you from very difficult-to-debug production
problems. It has a significant upfront cost in terms of "fighting the borrow
checker", adding extra annotations to your code, etc., so it's definitely not
worth it for every developer in every situation.

[1] [https://blog.golang.org/share-memory-by-
communicating](https://blog.golang.org/share-memory-by-communicating)

[2] [https://blog.golang.org/race-detector](https://blog.golang.org/race-
detector)

------
lidHanteyk
I will remember these talking points when talking to Rust prophets. That said,
although Rust is a mediocre language at best, Go is truly quite poor. Neither
of them are good languages, and Go will stay that way; only Rust can be good
in the future.

------
chooseaname
The problem, for me, with Rust is a lot of people who evangelize it seem to
think there should only be one programming language.

It's kind of a put-off.

~~~
kristoff_it
I would recommend not factoring that into your decisions. Yes it's off-
putting, but the technical merits of the language are truly there.

------
desc
Warning: brain dump ahead.

Broadly speaking, in any system, there is necessary complexity (imposed by the
problem domain) and unncessary complexity (imposed by the tools, the
developers, the customer's interpretation of The Matrix, etc).

Go aims to minimise the latter, which is a worthy goal: I understand _very_
personally how easily it is to add unnecessary complexity while trying to
'contain' the necessary complexity...

However, languages also provide useful and usable means to tame the necessary
complexity. It's a tradeoff.

These days I try to write C# like Go: no IoC, composition over inheritance,
specificity over genericity, etc. But enforcing those kinds of limitations at
the language layer places a hard cap on the abstractions available later on.

To some extent, again, that's a good thing: far too many abstraction astronaut
libraries in DotNet-land, spawned by someone's pet project getting
overgeneralised. Such things need to be better considered and better contained
within the developer group using them, unless they're _extremely_ well-
designed which is rare.

But if you remove the clean way to do something, people will do it anyway and
it will be a mess. Quite probably in an 'edge' codebase, in a system where the
senior devs have enough to deal with already, and the clique of devs looking
after that particular edge develop their own little dialect of the language.
(I don't care how much you think 'any dev can modify anything' in your code,
if you've got more than ~10 devs you have 'preferred' people for certain
areas, and some newbies will pick up some bits preferentially.)

Or you could give them a tool with higher-order concepts, and they'd be able
to work within its idioms.

Restricting the available idioms just forces people to create new ones. You
get doubleplus ungood code from that in fairly short order. Idioms get
generated when the culture doesn't already have them, and the culture
fragments according to the idioms its subcultures generate if they can't
crosspollinate effectively.

Don't try to solve a social problem with technology. Solve it with education,
discussion and code review instead. If you don't have time for that, you don't
have time to fix the mess resulting from the technical solution either.

 _That said,_ the smaller the service the less likely that it's going to need
to deal with higher-order abstractions. If you really are 'just' gluing
together services in interesting ways (note that the filesystem is a service
of sorts, and Git LFS is written in Go) _and_ you can confine your code to
solving _specific_ problems, you probably don't need the higher order
abstractions anyway.

In which case any other language could probably do the job too, to be honest,
but they'd make it easier to sprawl... which brings us back to a language
which puts an 'awkward' cap on making things sprawl.

Remember that it's very easy for a project to grow beyond its initial scope,
and choice of language can encourage, enable, smother or doom that, and any of
those outcomes can be good depending on your outlook...

------
pictur
Fanaticism in programming languages sometimes sounds very funny

------
trpc
I've read this article and I am yet to conclude why Go and not Rust. All your
talk is very generic and no proof or concrete argument to support article
title.

------
peterwwillis
Why <trendy language 1> and not <trendy language 2> ?

Maybe because trendy languages aren't a panacea.

~~~
red75prime
Maybe people aren't looking for the panacea, but to ease particular pains.

~~~
peterwwillis
We all use C instead of assembly because it makes it easier to express the
same thing, though we lose some control, and pick up bloat. Each successive
language tends to do the same. But once you're comparing languages that are
basically at the same level, what are you really gaining by switching?

There's always going to be pain. I think we just assume the _other_ pain will
be more tolerable.

------
johnklos
"Rust has provably-correct concurrency"? Too bad they're so busy being
passive-aggressive that they won't fix the build of Rust itself so that it's
deterministic.

------
cpursley
It seems like Elixir is a better fit than Go for all of the benefits listed
here, especially in the age of distributed systems.

[https://blog.codeship.com/comparing-elixir-
go/](https://blog.codeship.com/comparing-elixir-go/)

~~~
interfixus
Your linked article states quite clearly that Elixir does not cross compile,
and is best deployed via some deployment tool, seeing as it doesn't produce
easily managed, static, standalone executables like Go does. So it seems like
Elixir isn't.

~~~
floatboth
OTP release tarballs aren't much harder to deploy than static binaries :)

Elixir doesn't need to "cross compile" because its only compile target is
BEAM. That's like saying "Java doesn't cross-compile".

------
phlakaton
I tell folks that working in Go is like coming full-circle to C again. It is
the easiness of Go, the general presentation of good ole shoot-yourself-in-
the-foot pointers, and even the presence of interface{} as an analog of void*,
that causes the link in my mind.

As many of you know, the Go community has been having a knock-down drag-out
argument over whether/how generics should be added to the language. I joked a
bit about this, but I am serious in my contention that much of the value
proposition I see of Go over Java would be wiped away if a feature that
complex gets bolted onto it.

~~~
jerf
"the general presentation of good ole shoot-yourself-in-the-foot pointers...
presence of interface{} as an analog of void*"

Go doesn't have "shoot yourself in the foot" pointers. For that, you need
pointer arithmetic, and Go doesn't have that. (Outside of the "unsafe"
library.) interface{} may be an analog of void∗, but it lacks the failure in C
where casting something to void∗ loses all type information; in Go, if you put
an "string" into an interface{}, the runtime still knows it's a "string" and
you can't put it into any sort of strongly typed variable except a string. The
runtime/virtual machine Go implements knows the types of all values at all
times.

I really wish the Go designers had called their pointers "references".
Considered across the entire landscape of what various programming languages
call "pointers" and "references", there's substantial overlap but I think Go's
pointers are closer to the center of the "references" cluster than the
"pointers" one.

~~~
phlakaton
Not shootable in the foot in terms of pointer arithmetic, but shootable in the
foot in terms of unchecked dereferences of nil. As a C++ programmer
historically, I think of references as not being nilable.

~~~
Gibbon1
AKA has 'pointers' but not in a way that adds value.

------
dochtman
I have little doubt that Go is easier to get started with than Rust. However,
I'm very skeptical that Go "scales" better on any other axis than onboarding
new people quickly. Also not convinced the Go toolchain is better than Rust
(other than in terms of compile time).

Especially for "big scope", I place a lot of value on leveraging Rust's more
extensive type system and abstractions to model the "complex domains".

I would also bet that services written in Rust would be more robust than those
initially written in Go. Initially standing it up is, in the end, such a small
part of your long-term productivity, and Rust really shines in all the other
parts.

Seems to me that Go is more compelling than Rust for enterprise software
development because many businesses do a bad job of looking at their
development costs over a longer time frame, thus valuing short learning curve
over high reliability.

So really, it seems like the author does not have a profound familiarity with
Rust. Which is fine, but not a great basis for confidently expressing semi-
universal truths on your blog.

~~~
kjksf
I'm an open-source, solo dev. Not an enterprise dev. I use Go for most of my
projects.

For me, the biggest hit to productivity are long compile times. One of my
projects is ~80k loc C++ app (SumatraPDF) and I pretty much abandoned working
on it because the long compilation times are killing me.

Go is good in that regard. My medium sized projects compile pretty much
instantly.

I hear Rust is not doing well there.

The second productivity boost is GC (Garbage Collector). I don't want to
manually track every allocation (C++) or think about how to contort the code
to a form that Rust will be happy about.

Long term productivity is very much why I use Go.

In addition to GC and fast compile times, there's now a very rich ecosystem of
libraries for almost everything you might need.

The language has been stable in past 10 years. I don't need to fix the code
every major release because language changed (Swift) and I don't need to learn
a large number of new things because of significant new addition (Rust).

And for what I use it (backend servers, cmd-line apps) Go is more than fast
enough (which can't be said about out languages that have similar
productivity, like Python, Ruby, Node).

If there's a C++ competitor I'll be willing to look at, it'll be JAI (when
it's released).

