
Go vs. Rust: Writing a CLI Tool - JeremyMorgan
https://cuchi.me/posts/go-vs-rust
======
SiVal
I'm puzzled by one of the conclusions: Go is better "if you target
exceptionally/mostly Linux". But Rust is better "If the project targets many
operating systems and I want a truly multiplatform codebase".

I have no idea what this is referring to. The first time the article mentions
this (whatever this is) seems to be in the conclusions. Find the word
"platform" in the article, and there is one match: in the conclusion.

I write Go on Mac or Win, deploy on Mac, Win, or Linux. One code base, one
command-line option to tell the compiler which platform to target. A 2-second
compile for local platform, test, it works, another 2-sec compile of same code
with a different command-line option and I have a native executable for some
other target platform.

I don't know what more Go would need for the "truly multiplatform codebase"
that Rust purportedly allows, but I haven't used Rust. If I had to guess
(again, the article doesn't seem to say), I'd guess that maybe if I were
targeting something tiny, like a chip in a microwave oven or maybe WASM, Rust
would be better, because you can customize the memory handling. I would
certainly (learn and) use Rust over Go for such specialized cases, but then
those are "specialized" cases, not general multiplatform cases. I wouldn't
deploy the same code to a microwave oven and Windows.

So, I don't know. Any ideas?

~~~
TheNorthman
He does link to an article [0] that mostly talks about multi-platform Go and
uses Rust as a language that doesn't have these problems, to the same degree
at least.

The gist of the article is that, while Go might very well compile easily on
multiple platforms, it does so not by solving the complexities inherent with
this problem but rather by merely hiding them from the user.

There are plenty of examples in the article so I won't elaborate on that part
but his examples mostly revolve around $(platform)-specific features being
poorly poly-filled on non-$(platform) platforms.

[0]: [https://fasterthanli.me/articles/i-want-off-mr-golangs-
wild-...](https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-ride)

~~~
est31
I skimmed over that article and most of the criticism is about OS API
wrappers. The thing that enables Go's single command cross compilation is
thanks to other components of the pipeline being implemented in Go, like the
linker, or not needing Windows import libraries (there is a merged RFC for
Rust called raw dylibs to solve this, but implementation has stagnated... go
has this feature already).

In the long term, Rust may end up in a better place than Go regarding
portability but of course as long as GCC can target more than clang and there
is no Rust gcc backend while there is a Go backend, Rust can't be better than
Go in all portability aspects.

------
malechimp
>> I want a very simple language for my teammates to learn

I feel this is said in a demeaning way plus it is not true IMO plus if I had a
penny for every time I read that I'd probably be much richer by now.

Go is _not_ a simple language to learn _correctly_. It is only simple if what
you're trying to do is simple which goes for almost any production language
that is not designed to drive you nuts. And it should be simple at that. A
language is a tool. It should be easy to use in order to solve easy(ish)
problems and feel progressively more difficult as the problem domain gets more
complex. Having a language that gets in the way right from the beginning makes
you focus on the language rather than at the problem at hand which makes for
bad overall solutions.

Example: If you still feel that Go is simple to learn try to read some
kubernetes code.

Having said that, I accept that Rust is way harder to get to grips with. My
question is why should I though? I understand the appeal of Rust up to a point
but I think much of it as a bad form of machismo - something quite common in
the industry and also quite destructive. To me Rust is a better alternative
maybe to C and C++ but that's about that. If you program systems and you
absolutely do not want a garbage collector doing its thing then by all means
go for it. For everyone else though I don't get why you should try to climb
your project mountain in flip-flops. Not saying that it can't be done. Not
saying that you won't get extra wow points for doing it. Just saying that you
don't need to.

~~~
yahyaheee
> If you still feel that Go is simple to learn try to read some kubernetes
> code

The Go code in K8s is simple, the system of Kubernetes is complex

Rust isn’t about machismo, it’s about high performance computing. Try writing
graphics or machine learning code in Go, it’s not about being tough it’s about
having a tool that can actually do the job.

~~~
harpratap
> The Go code in K8s is simple, the system of Kubernetes is complex

Can you link me to a doc which explains the runtime scheme type system of
Kubernetes? Could never wrap my head around how that even works. And why they
had to even do this in the first place?

~~~
yahyaheee
This is the best I can find [https://kubernetes.io/docs/reference/using-
api/api-concepts/](https://kubernetes.io/docs/reference/using-api/api-
concepts/) there used to be a better doc on this but I can't seem to find it
again.

Runtime scheme and the k8s machinery can be pretty awkward. Scheme is just a
way of registering the available datatypes by group/version/kind so the client
can look at any given object and figure out if it knows how to decode it.

~~~
harpratap
This doesn't explain it at all, specially the ecosystem surrounding schemes -
informers, cache clients and various other code generators for typed as well
dynamic API clients

------
miccah
> Rust has:

\- monadic constructs (Option & Result) \- the error propagation operator \-
the From trait, to automatically convert errors on propagation

> The combination of the three features above makes up the best error handling
> solution I saw in a language, being simple, sound, and maintainable at the
> same time.

I absolutely agree with this. The error handling in Rust is fantastic to work
with.

Once I learned about bullet three, error handling became less of a chore and
more of non-issue while staying confident that any errors would be handled
correctly.

~~~
wwright
The “anyhow” and “thiserror” crates remove a lot of boilerplate, too. I hope
something like that gets merged into std.

~~~
say_it_as_it_is
Wanna know a quick way to reduce your compile time by several seconds? Skip
proc macros that you can impl manually. The Error trait is one such case where
the boilerplate impl is worth it.

------
ThanhMB4332
Most importantly, like many articles and discussions regarding Rust, this
article misses the point. It's not about high end language features. In 99% of
the projects it's also not about computational performance (but latencies -
memory, network, disc and scalability).

Success of our projects is ultimately shaped by the development process, the
matureness and reliablity of the ecosystem (standard lib of Go) and ease of
use of the tools, so you can focus on the problem to solve.

Besides of that: I haven't written much Rust, so I can only comment on the Go
side:

I never heard of GVM (local env for Go) - probably because it's not needed.
Just use Go modules. Really, no need to worry about GOPATH etc.

Regarding the conclusion:

Rust is ultimately faster and uses less resources, no dispute here. However,
there're no benchmarks in the article. For the given CLI application, the
result would very likely be: There's no performance difference.

However, Rust is not generally safer than Go. Rust is safer compared to other
language with manual memory management (C/C++). Rust has a stronger
typesystem, but that doesn't mean Rust programs can't panic too.

~~~
c-cube
Rust is a bit safer.

\- it warns you if you ignore an error. \- it forces variables and fields to
be initialized. \- it has sum types and generics instead of interface{}. \- it
prevents some race conditions at compile time. \- it pushes programmers
towards immutability.

~~~
pkolaczk
It doesn't only WARN about ignoring an error, it refuses to compile. T and
Result<T, E> are different types.

~~~
saturn_vk
I've always wondered whether "unwrap"-ing is considered ignoring? I personally
always equated it to ignoring if there's an error

~~~
steveklabnik
I would say no, because it's not ignored. It makes it explode.

------
teleforce
Apparently there is a new book (beta stage) dedicated on Go for CLI tools and
applications [1].

Personally I think it'll be interesting to include D as well for more complete
comparison due to it also fits the bill and it's no slouch either. A very fast
TSV CLI tools written in D by eBay is covered in HN last year [2].

It'll also be very cool and useful if someone could write CLI tools in any of
these compiled languages for supporting Arrow, Parquet and TileDB data formats
[3].

[1] [https://pragprog.com/titles/rggo/](https://pragprog.com/titles/rggo/)

[2]
[https://news.ycombinator.com/item?id=20848581](https://news.ycombinator.com/item?id=20848581)

[3] [https://www.i-programmer.info/news/197-data-
mining/13263-new...](https://www.i-programmer.info/news/197-data-
mining/13263-new-database-for-data-scientists-.html)

~~~
pizza234
> Apparently there is a new book (beta stage) dedicated on Go for CLI tools
> and applications [1].

I own that book, and I have two considerations:

1\. I've found Golang simple enough not to need particular education on
building simple tools; the book itself is well-written though, for people who
like to be accompanied or motivated in learning a subject.

2\. they've labelled "beta 2" (!!) a book where 40% of the content hasn't been
written; in the software world, this would be (rightfully) ridiculed.

------
st3fan
> The first problem I found using Go, was when I was figuring out how the
> module resolution worked along with the GOPATH, it became quite frustrating
> to set up a project structure with a functional local development
> environment.

Really?!

There is no magic. Create a directory anywhere and run go mod init. There is
NO need for go virtual environments.

This is all well explained in the documentation. The first section of
[https://golang.org/doc/code.html](https://golang.org/doc/code.html)

Really unfortunate the author missed this because the go tooling is really
excellent and in 2020 you don’t need to know anything about GOPATH.

~~~
da39a3ee
Personally, as someone who doesn't write Go but occasionally tries to compile
Go projects, GOPATH/GOROOT caused me problems all of the last 3 or 4 times
that I tried to compile a Go project, and I struggled to find clear
explanations of what they should be set to. I felt like I was being stupid,
and I'm sure I should have read the documentation better, but nevertheless,
there's my data point.

~~~
ithkuil
Indeed that was a problem for many people and a key motivating factor to
deploy the new go modules approach (which is enabled by default for a while
now). Most of the projects out there now contain a go.mod file.

That said there may still be projects out there that are unmaintained or the
author didn't bother to convert to go.mod, so you might occasionally still
encounter GOPATH.

~~~
dpc_pw
That's aggravating the problem. No only the original way was painful, but now
there are multiple ways and to the newcomer that just needs to contribute to a
project - it's all one big mess.

~~~
nomofomo2
Agreed! I pick up Go a few times a year (which doesn't help, admittedly) and
even consulting the official documentation, it's hard for me to figure out
what the current, correct way of doing things is.

~~~
ithkuil
If you want to learn this my suggestion:

Dedicate 30m to read [https://blog.golang.org/using-go-
modules](https://blog.golang.org/using-go-modules) and try it out with a small
demo project,e.g. write a small tool that emits a uuid; keep the toy project
very small so you don't encounter other problems that might distract you from
learning the basics of dependency management.

Search for dependencies using pkg.go.dev.

------
elephant_talk
Great comparison, but I’m sad that D lost out in the popularity wars. Talk
about a versatile workhorse that is appropriate for 90% of (non-GUI) tasks.

D is a valid competitor of Rust, that just happens to smash Go in the process.
All the ergonomics of a high level language like c#, decent (toggleable)
garbage collector, the ability to write all your scripts in it... the list
goes on.

It lacks options in the editor and tooling department (although VS Code
support is great), but that comes with community size.

~~~
vips7L
D also has LLVM and GCC back ends so you can target every architecture.

Other things it has over go:

Generics, inline assembly, kernel threads, and great interopt with C/C++.

~~~
tandr
How is the compilation speed - instant (close to Go), seconds (like C# or
Java), something longer (like C++, Rust)? Sorry, I have not used D
extensively.

~~~
apta
> instant (close to Go), seconds (like C# or Java),

golang compilation is about the same speed, if not slower than Java or C#.
Especially for larger projects.

------
denysvitali
I love Rust, but a few drawbacks made me choose Golang over it:

\- Compilation Time \- IDE experience: I have yet to find a good IDE that
works like Goland does for Golang, this anyways is due to the compile time :(
\- Non-static binaries by default \- Too verbose (compared to Go) \- CLIs are
not that easy to write compared to Golang, but this might be due to the fact
that I have yet to find a similar library to alexflint's go-args for Rust \-
Lifetimes: I'm too stupid to understand them properly, and I get frustrated
when I think I understood them and then I spend half of my development time to
fix an ownership issue

Again, I _love_ Rust language, but I very much hate its compiler, and thus my
general development experience. If RLS and the Rust compiler were as fast as
Go's one, I guess that the whole experience would be much better for me.
Additionally there isn't really an IDE for Rust that works like Goland for Go
:(

I have to admit that I'm much faster at writing Go CLIs (and I wrote a lot of
CLIs in the past couple of months), but I might be biased for the reasons
explained above that didn't let me enjoy that much programming in Rust.

For a private project of my own, composed of three libraries, I spent most of
my time fighting with the borrowing system and the verbosity of the language
itself (like `pub field` rather than Go's `Field`) or the whole
`json:"fieldName"` annotations that Golang uses.

Last, but not least, I can cross compile Go projects from my Linux computer
targeting Windows without any cross compiler toolchain, and the resulting
binaries are static. This is a feature I love!

I would very much like to have somebody providing me with tips on how to
improve my Rust experience

~~~
steveklabnik
Have you tried IntelliJ-Rust? I am curious how it differs from Goland (I've
never used it.) I personally use VS: Code with rust-analyzer, which is the
successor of the RLS, and much better.

structopt will give you a go-arg-like experience. clap 3 is going to adopt it,
in my understanding, so that reduces the number of packages.

~~~
denysvitali
IntelliJ Rust is good, but has still the same problem as any other IDE for
Rust (that is, RLS performance). You have to wait 5-10 seconds to get a
feedback from the compiler :(

The combination that works better is Clion + Rust plugin, but just because you
can easily debug w/ gdb.

I still have to try Rust-Analyzer, first time hearing it - hooefully this will
improve my developer experience: heck RLS is slow as hell even with vim :(

Thanks for the tips Steve!

~~~
steveklabnik
Ah, IntelliJ-Rust doesn’t use the RLS, as far as I know, so I wasn’t sure how
its performance compared.

rust-analyzer is way way faster.

Thank you for elaborating!

~~~
denysvitali
Thank you for your tips! I'll try again to dive into the Rust ecosystem,
hopefully with a more happy outcome thanks to your tips :)

------
savaki
You may want to consider looking into go modules. It works much the same way
that cargo does for rust and you won’t need to worry about GOPATH for most
cases.

------
panpanna
Author writes that this started as an interview project.

If someone showed you this article in a go or rust job interview, would you
consider him for hiring? Why/why not?

~~~
linkdd
The author proved he knows how to learn, how to search, how to analyze, how to
compare two technical solutions.

The methodology is there.

I don't even care if he doesn't know the language we are using, I care about
how he thinks because that is the skill used to solve problems.

------
basedtho
I love this font

~~~
donut
Looks like Iosevka Sparkle.

[https://typeof.net/Iosevka/](https://typeof.net/Iosevka/)

~~~
basedtho
Thanks!

------
Insanity
The conclusion missed the fact that Go is also multi-paradigm. It just misses
the syntactic sugar, but that's not to say you can't use Go to program in
multiple paradigms.

I don't entirely agree with the statement that Go seems to not work on Windows
("if build mostly for linux"). Go works fine on Windows, although I do agree
some tooling just works better on *nix, but that goes for many langs :-)

It's good to see such a comparison form the perspective of a novice with the
languages, but it'd also be interesting to get such a view from someone more
experienced with both.

The source code is not bad though! Although the project structure could use
some work :-)

