101 comments

[ 3.2 ms ] story [ 165 ms ] thread
"Rust competes for mindshare with C++ and D for programmers who are prepared to accept more complex syntax and semantics (and presumably higher readability costs) in return for the maximum possible performance. For example, micro controllers, AAA game engines, and web rendering engines.

Go competes for mindshare in the post 2006 Internet 2.0 generation of companies who have outgrown languages like Ruby, Python, and Node.js (v8) and have lost patience with the high deployment costs of JVM based languages."

They forgot the mindshare of PHP users. The tradeoffs Go makes are rather similar (simplicity, ease of deployment vs expressivenes and consistency).
I saw a tweetstorm by a longtime Go user who listed all the flaws and inconsistencies of the language. In the end it didn't look much better than PHP to me. Which is surprising, since PHP is a "grown" language and go has been "designed" by some longtime languages pros.
A lot of complaints usually affect niche or rare use cases in the language (or you learn them fast).

Though I guess the same applies to PHP.

It's a lot nicer to write webapps in Go though since you have control over global state and not the per-request state of PHP, which makes for some easier solutions to problems (work-queues are easy to implement/use on the server-side unlike in PHP)

Also the stricter type system compared to PHP is nice in addition to static linking making it more portable than PHP (minus not being portable to shared hosters)

Yes, I'm not a big fan of PHP either.

Guess the global state access and easier parallelization are the main selling points.

I wrote a few APIs with long running queues in PHP and Node.js and found it both a bit too clunky for that job.

I don't think there's anything inherent in the language that prevents PHP from running like Go (daemon that receives requests, rather than being launched by an external server on each request). It's just a matter of convention.
Comparing PHP with Go it's a bit too much, don't you think? Type system, standard library, concurrency, compilation, packing ... I hardly find similarities.
I can't agree though. I believe using that rationale same could be said about C and many other languages...If that's the case then, should we expect a "fix" for the master programmers (i.e. Go++)? Let's hope that won't happen. Go is nothing like PHP. It was an attempt to modernise C though I believe it failed because Go can't do realtime.
C is far from perfection, but it's very small, fit well to the hardware of its day, and had a colossal "killer app", Unix.

A fix for master programmers is e.g. Rust, and a bunch of GC-based languages, from newcomers like Crystal and Nim to the battle-hardened JVM ecosystem, or Erlang/Elixir.

The way C++ did not displace C, or the way Ruby and Python did not displace PHP, these guys will not displace Go.

>and go has been "designed" by some longtime languages pros.

Longtime systems and UNIX pros, not language/compiler pros though. That would be someone like Anders Hejlsberg or Lars Bak respectively.

Is that why Dart got so popular compared to Go? What about C?
>Is that why Dart got so popular compared to Go?

No, that was because the focus of Dart (replacing JS on web browsers) wasn't feasible, and even Google dropped it. Which says nothing about the quality of the language (which was selected for the Flutter SDK anyway).

Besides, popularity in tech, as in high school, doesn't say much. Engineering shouldn't be a pop culture.

>What about C?

What about C? That was made by Dennis Ritchie, not involved in Golang. And even so, it's not the best basis for a 2007-2017 language.

I think the bottom line for a language is to be successful not whether or not the founder has whatever acreditation someone worships. I believe C has been pretty successful thus the reason why I was asking you about it...was Dennis Richie a compiler designer or a unix developer? Dart seems to be used pretty much only by Google with few exceptions. I'm not saying it's a bad language but it's just not successful. I believe popularity is important because a death language doesn't solve problems. Engineering is about solving problems anyway not about developing the most complex/expressive language.

As far as Go design is concerned I believe that someone who designed few programming languages can be called a "pro" even if he doesn't agree with the mainstream opinion about what makes a good design. Simplicity is underestimated.

Though one thing that Go has which PHP doesn't is the rapidly braking changes (PHP3 and 7 have totally different idioms since early PHP decisions proved to be horribly insecure (register_globals))
A Wordpress alternative in Go would be pretty cool. Is anyone working on such a thing?
Perhaps this: https://gohugo.io/

There are bunch of comparisons Hugo vs Wordpress on internet.

Imagine a one-step converter: "put your WP configs here, take your [Go-based] new site there, just 3x faster", or something.

Good static site generators are many. The point of a product might be near-zero transition friction.

This actually makes a lot of sense. From the outside, it's hard to see why anyone uses Go. Using Go feels like going back in time 20+ years.

However if someone is coming from PHP, Go must look positively modern. Considering the millions of PHP programmers out there, Go can keep on growing for a long time.

Coming from a scripting language background Go was like moving into the future: concurrency primitives, static linking, channels, fast compile times, awesome standard lib.

Not to mention the fact that go fmt makes everyone’s code look exactly the same. No more weird, personal styles being brought into into source code or pointless discussions of naming conventions or indentation.

Concurrency primitives maybe (though languages had those for 20 years too).

But what about static linking, fast compile times and awesome standard lib is like "stepping into the feature"?

Static linking: no more futzing around with package nightmares on systems. Making sure system packages are present so python virtualenv can install. Static linking makes portability a breeze. I don’t know why this idea was lost in virtually every scripting language from the past 20 years.

Standard lib is just plain awesome. You can build most things right out of the box without searching the web for competing versions of the same thing. Web apps are a great example.

Fast compile times was a feature built into Go from the beginning. Presumably from people frustrated by compile times of large C/C++ codebases [1]. It’s about developer productivity.

1. https://golang.org/doc/faq#What_compiler_technology_is_used_...

> Static linking makes portability a breeze. I don’t know why this idea was lost in virtually every scripting language from the past 20 years.

Because they are invented at a time before storage and RAM is dirt cheap and lightning fast. It was painfully wasteful and slow to load a copy of the standard library for every process. Dynamic linking was invented basically because static linking wasn’t feasible.

For me, coming from Java it was a breath of fresh air simply because of the simple build setup. (Modern) Java requires gradle (which is a magical setup, written in a language totally dead outside of gradle scripts), special magic for a "fat jar", and even then it doesn't create a exe/elf at the end. And the build is fast - even on a raspberry pi.

Oh, and the IDE environment is amazing - you literally don't need much more than VSCode or vim (the language tools have built in refactoring support, formating, quick compile for syntax error, godoc).

And you have closures, something Java didn't have until 8, and even now many libraries don't support it.

I am not sure if many programmers are "prepared to accept more complex syntax" (etc.) than those of C++...
Thankfully that wasn’t implied at all, and it’s not true that rust has more complex semantics (or, I think, syntax, although I could be wrong on that).

That said, it certainly is more complicated refactoring arbitrary data flows. There is certainly a cost for all the benefits! :)

(comment deleted)
I think the author is saying "more complex" relative to higher level languages like Go. They mean to put Rust in the same category as C++. It could be rephrased as "prepared to accept languages like C++, D, and Rust with more complex syntax"
Curious, what are the "high deployment costs of JVM based languages"? Don't must standard workloads simply deploy a jar?
Likely they mean high RAM consumption?
I assume this refers to the overhead of the JVM itself. How high that is and how much that matters has been subject to debate, but I think it is objectively higher overhead cost than the Go runtime.
To simply deploy a jar you need to have jar compatible JDK installed on that system. The effort towards that IMO is non-trivial.
Until Java 9, not a lot was done about the memory footprint of Java. Especially Strings, which were all stored in UTF-16 internally. For a language prone to Stringly Typed coding, that makes containers a hard sell, but caused issues just running it on VMs long before containers were a thing. Really this is something that should have been started for Java 7 and completed in 8.

They also kind of hit a wall around 1-2GB of memory that took ages to get past with GC. It had the potential to kill your 95th percentile numbers to have long GC pauses. It contributed to things like Redis and Memcached taking off because of how frequently you needed data close to you but couldn’t just keep it in process.

I suppose that "high-deployment costs" also includes JVM/application startup and warmup.
Most likely some old myth regarding the JVM.

Its actually trivial to deploy and updates are just pushing one file; your uberjar. This is so much better than anything node/ruby/python/php have to offer.

I also feel much safer running code in a VM on the server than directly native where a single invalid dereference brings down the whole thing in a rain of fire.

The unbelievable irony I'm observing with the Java-based things I need to deploy these days (Jenkins and Gerrit related) are that quite often they're making me build something, which then fails due to weird maven issues I don't understand (since I haven't been a Java dev since the ant days).

The entire point of java was that bytecode is portable, it's "write once, run anywhere". Don't make me build your stupid .jar and figure out all your dependency / build-time issues, just give it to me!

I don't think Jenkins is a good indication of modern Java :) If anything Jenkins is a hairy ball of mud you should try to avoid :p

I write exclusively Clojure on the JVM now; its like having all the advantages of the JVM and none of the inconvenients of Java!

Without using containers or fragile (and not very portable) executable wrappers you need to manage the JRE, JAR files and the right classpath.

With go you can just run 'go build' and get static executables for all common platforms with zero dependencies.

The key difference between that and just throwing jar files on random systems is that static executables truly work anywhere and will never crash because you don't have the right version of JDK and usually won't need messing up with arcane command line parameters or .properties files.

Deployment is one area where Go truly shines and I guess that helped its popularity. PHP also got immensely popular due to ease of deployment, although of a different kind, in a different era and with different expectations.

(comment deleted)
I remember reading somewhere that Go was originally intended to take over a lot of projects that are currently C++, and that it was kind of a surprise that more Go programmers ended up coming from languages like Python. If that's right, it might be fair to say Rust and Go were "originally" competitors, even if they aren't as much anymore :)
>I remember reading somewhere that Go was originally intended to take over a lot of projects that are currently C++, and that it was kind of a surprise that more Go programmers ended up coming from languages like Python.

Yes, I think that was in an article by Rob Pike, might have been his article titled "Less is exponentially more."

Edit: Found that article:

https://commandcenter.blogspot.in/2012/06/less-is-exponentia...

Excerpt: [ I was asked a few weeks ago, "What was the biggest surprise you encountered rolling out Go?" I knew the answer instantly: Although we expected C++ programmers to see Go as an alternative, instead most Go programmers come from languages like Python and Ruby. Very few come from C++. ]

(comment deleted)
Ha ha, my edit and your reply (which you later deleted) crossed in time, due to my messing up my original post a bit w/copy+paste :) Sorry for the confusion. Anyway, point made clear. I found Rob's statement surprising too. But also, I heard from Josh Fraser, founder of Torbit (acquired in a relatively short while after being founded), that they decided to use Go because it has a good balance between the performance of C and the productivity of dynamic languages like Python and Ruby.
I mean hell, Rust even had a GC and Green Threads at one point.
As a C/C++ developer that doesn't surprise me at all. I looked at both Go and Rust and I'd go with Rust if given a choice between the two.
It might be that they underestimated how desperately people had already moved away from C/C++ if they had any choice at all :)
One of the reasons for the confusion from those of us on system programming side is that Go inherited mostly from Oberon...

https://blog.learngoprogramming.com/about-go-language-an-ove...

...that was used to build OS's and other system stuff. Here's a brief history I just submitted and the official pages.

https://news.ycombinator.com/item?id=15704806

http://www.ethoberon.ethz.ch/

http://www.projectoberon.com/

The Delphi product and the Oberon offshoot Component Pascal were used as C++ replacements. Here's an IDE for Component Pascal:

http://blackboxframework.org/index.php?cID=home,en-us

So, the point is that it's a variant of a Wirth-style language for writing operating systems and low-level apps. With that, many of us figured it can also target the same thing. It might need some modification in its runtime or something if not originally aimed at it. I see no reason why a language stronger than Oberon couldn't be used for at least what Oberon was used for, though. As partial evidence, people are already writing prototypes for OS's in in.

https://news.ycombinator.com/item?id=14537691

https://www.phoronix.com/scan.php?px=MTY5OTQ&page=news_item

Throw in real-time or selective GC's as a modification to get it closer to taking over a lot of stuff that C would be doing. There's also nothing stopping the low-level code from being straight-up unsafe with checks added by programmer since that's already the baseline with C. One would get a more pleasant language that was at least memory-safe in other components that could take a GC. House OS is an example where the H Layer wraps the unsafe, lowest-level parts of the kernel of an OS mostly written in type-safe Haskell.

There will be some crossover since Go's AOT compilation and low latency pause times will make some things that needed to be done in C++ or Rust viable in Go.
>> make some things that needed to be done in C++ or Rust viable in Go.

like "micro controllers, AAA game engines, and web rendering engines"? I highly doubt it! Swift 5+ might have a chance but Go has none(as it is now).

> Swift 5+ might have a chance but Go has none(as it is now)

As long as it lacks Windows support Swift has no chance to be even considered for an AAA game engine.

That seems relatively easily fixed, if any biggish company cared enough to do it?
Yup, like the post about Discord processing images from yesterday underscored. If you need top tier performance you're going to have to reach for a language like Rust, C or C++ because without discrete control over your allocations and memory placement you will have something slower.

C# is about the closest thing these days thanks to value types but even then Unity had to drop down to C++ to really get the performance they needed at the engine level.

Yeah, but it seems to be fine for something like Docker.
Sounds like you're advocating a Rocker project.
Docker could also have been written in Java or Python, though, because most of the heavy lifting is provided by the kernel.
Docker is more I/O bound than CPU bound, so Go is just fine.
I wrote the most non-idiomatic C# in Unity to create a lighting fast 2D skeletal animation system (100-1000x the performance of the closest competitor) and I'm certain I could've gained yet another order of magnitude had I access to C++ instead of C#.

C# is fine for scripting, but absolutely terrible for performance critical batching where branch predictions and cache misses are your main optimization points.

Also the lack of array slices make it really hard to avoid memory allocations.

Yeah, that's my biggest gripe with the "GC'd language are as fast as native" crowd. You end up doing all sorts of contortions in order to get the allocation/cache coherency that you need that you're better off using a language that has proper support for it.

I love scripting languages for orchestrating logic(luaJIT!) but when you need to massively vectorize your data so that you get full utilization of the prefetcher there really is no substitute.

c++ is used in a lot more than just "micro controllers, AAA game engines, and web rendering engines".
C++ is used for everything(including web development) so any language can replace C++ in various use cases.
Many controllers are not hard-realtime. Think e.g. of microwave ovens or smart locks. Often you might be willing to trade a 10ms GC pause of Go for much lower chances of memory corruption or crashing compared to C.
Many controllers have almost zero memory headroom meaning your GC pauses get an order of magnitude slower if not more as you have less than 2x your working set.

Also, most of the applications never allocate because they can't even afford the overhead of pooling/freelists that come with a stock malloc implementation.

is a gc all that relevant if you're not dynamically allocating in either case?
Garbage collection by its nature implies dynamic allocation.

You're using value types and raw pointers in those targets because even the memory overhead of a heap/freelist/etc can be too much. With things like AVR you're looking at 512B to 16kB of total memory(part of which includes the code you write).

> Garbage collection by its nature implies dynamic allocation

i'm not sure i follow - you're saying that a gc existing implies that one cannot preallocate and avoid dynamic allocation?

> preallocate

This will still use dynamic allocation to do the preallocation. You'll have a heap to track this which comes with its own overhead.

i guess i was using 'dynamic allocation' to mean allocation that occurs in the midst of the main control flow, likely in response to some conditional evaluation (vs upfront).
Yeah, if you allocate in the main loop or preallocate you're still going to pay the overhead of a heap to keep track of those allocation :).
I’m developing software for WiFi routers. I would have liked to use Go but the binaries are simply too large and compilation is sketchy for ARM.
I wonder if Rust could fit your bill better. You can include about as little runtime as you like, no GC or language primitives runtime to carry if you don't choose to.
>> Often you might be willing to trade a 10ms GC pause of Go for much lower chances of memory corruption or crashing compared to C.

I believe the C/C++ developers will look for a Rust-like solution(even if I don't like Rust) rather than Go if crashing is an issue. Go doesn't solve the crashing issues. It has its own crashing issues(e.g. dereferencing nil pointers , deadlocks, data-races, nil and nil interfaces etc). If the GC is not an issue they can choose any other GC language so Go is not that special anymore in this regard. The truth is that Go has its own niche and that's web services.

Like AA games/game engines, and some micro controllers sure. Desktop applications like text editors where waiting for JITs and high pause times are annoying unlike things running on server as well.
I don't see Rust as ready for AAA game engines, not by a long shot.

Last I checked it had absolutely terrible reflection capabilities and meta-programming; both of which are used as the foundations of modern engines.

A game engine is also radically different than your usual use of Rust; its almost impossible to model with borrows without going dynamic and those come with runtime overhead; something not acceptable when you're used to zero-cost abstractions.

A web rendering engine has ridiculously less state and moving parts than a game engine. D would be a much better fit for game engines than Rust.

MORE of these headlines instead of "Go is slower than Rust" or "Rust has more bells and whistles than Go".

I develop in both Go and Rust.

I use Go as main replacement for .NET/Java web tier...no need for install specific Java or .NET run-time library.

I use Rust when there's heavy disk reads and writes...and I know it's a nightly job which should never segfault and never finish the execution since it crashed.

GO = useful for rapid prototyping and a good .NET/JAVA middle-tier replacement.

RUST = you CARE about performance.

You can use both with FFI/C - use Go as the carrier and use RUST where the functions should squeeze every bit of performance to do something...

If you want rapid prototyping I don't think you can beat Clojure, not even close.

Its really, really hard to beat the iteration cycle of a Lisp.

Python is not too shabby for this either. Command line + vim (substitute your $EDITOR) and ipython and python and things can fly.
I actually think that in the long run Rust and Go will have a similar relationship between Ember and React. They'll have fundamentally different approaches, but they'll steal the best ideas from each other (for example, Glimmer is heavily influenced from React) and they'll both end up serving their domains better and maybe overlapping a bit more here and there.
lol, good comparison.

But what did React steal from Ember and what did Rust steal from Go?

There are lots of areas of speed optimizations that Ember introduced after switching to Glimmer that React stole. Plus their CLI is very, very heavily influenced by Ember's (which was influence by Rails).
They have a CLI?

I only knew about CRA.

All the languages end up serving their domains better and maybe overlapping a bit more here and there depending by the domain you are talking about.
They are both being used, where C and C++ were the only alternative

Some of the points to be made here is that C and C++ are being used for a very wide range of applications

So if you do compare Go and Rust, you will find distinct technical advantages and disadvantage

Rust/Go are currently the C/C++ alternative

But it seems to me that Go is used especially by non C/C++ devs.
well, people wrote servers in all sorts of languages

I like to think of it this way (image the line below is the range of software c/c++ is being used for, systems software on far left and apps on far right)

(systems)------------------C/C++------------------(apps)

People coming from left prefer Rust, people coming from the right prefer Go

Of course it is and it makes sense. Learning safe and correct C/C++ is a big challenge. You can do this, or write it in Go. It will be 80% as fast but take you much less time. It will also be safe.

Once you’ve learned all of the ins-outs of C/C++ then you don’t have an incentive to use Go to replace them. When you don’t need performance you can use a scripting language like ruby or python. I see this happen often.

> They are both being used, where C and C++ were the only alternative

> Some of the points to be made here is that C and C++ are being used for a very wide range of applications

That's a really good point. C is an odd language: people used it to squeeze every ounce of performance out of machines, even when they didn't need to. E.g. an ls or cat written in C is almost certainly a premature optimisation. Even a program like Sendmail should probably have been written in something like Lisp or Go (had it existed) rather than in C (and anyone over a certain age knows the high price of Sendmail being written in C: vulnerability after vulnerability).

People were using C almost as a scripting language, which in retrospect is insane. Using it as a portable assembler to build the bulk of an OS, or at least the low-level parts of an OS, made sense — trying to use it for high-level programming was a mistake.

I write Go every day, but I'd like to take a look at Rust eventually. I wonder if decent Rust can be written as quickly as decent Go can.

>People were using C almost as a scripting language, which in retrospect is insane. Using it as a portable assembler to build the bulk of an OS, or at least the low-level parts of an OS, made sense — trying to use it for high-level programming was a mistake.

Before C++ and some of the less and more recent higher-level languages became available and were stable enough, people were writing both business applications and desktop / server software products in C - a lot.

Biz apps that required database-like functionality were written either using ISAM-type libraries or low-level proprietary database APIs (specific to a particular database server) or using embedded SQL in C (e.g. Pro-C for Oracle, ESQL/C for Informix, DB-Library for Sybase, etc.

And lots of successful Unix and Win32 software products were written in C, for both the logic and GUI parts of the apps. I've worked some earlier on real projects / products of all those types I mentioned (except Sybase).

Some higher level products such as 4GLs also existed (for reporting and other purposes) and those were used too, but C was still used, even for business apps. When there were less of good higher-level-but-still performant choices available, and hardware was not as powerful, it was not an insane option at all.

Plus, as is known to C programmers, "in C you can do anything." Not many higher-level languages can say that - except by linking to C libs via FFIs of some type. Obviously there were cons involved too, such as string handling, memory and pointer management, and less productivity than higher-level tools.

https://en.wikipedia.org/wiki/Embedded_SQL

https://en.wikipedia.org/wiki/Pro*C

https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0...

An article about rust from 2015? Not worth reading.
Would the comparison have been more apt back when Rust used to have a garbage collector?
And green threads! But maybe that was all before Rust was prominent enough to count as a serious competitor?
> Go is focused on concurrency as a first class concept. That is not to say you cannot find aspects of Go’s actor oriented concurrency in Rust, but it is left as an exercise to the programmer.

To be fair, concurrency is baked the Rust type system itself. It's certainly a first class concept. I think the better way to describe it is that Rust wants to make concurrency safe regardless of what mechanism it's based on (system threads, futures/asyncio, maybe other things eventually?), while Go wants to provide a particular (very convenient) mechanism as part of the language.

I do not see that concurrency is a first class concept in Rust at all. The only mechanism that is in the language are the Send and Sync traits, and is even partially out of it.

Rust do not have language constructs for any concurrency/parallel model, and this is a good thing. You can use fork-join, parallel iterators, mutex, rwlocks, channels (mpsc, mpmc...) or any other model as a library.

The nice thing is that, as you say, is the type system the component that guarantee a free from data race code in safe Rust.

Yes I think we're mainly using "first class" to mean different things, but we can both agree that Rust and Go have both been designed very carefully around concurrency :)
This sounds like an attempt to box Rust into a much smaller niche than is justified.
I think the illusion of competition mostly comes from how Go was touted when it first came out. To quote the google announcement:

"For that reason, Some smart Google engineers decided that it’s time to address the limitations of C and C++ by designing a new programming language: Go. [...] Go is based on the C programming family, one of the most widely used programming language trees in the world [...] Go attempts to combine the development speed of working in a dynamic language like Python with the performance and safety of a compiled language like C or C++.We’re hoping Go turns out to be a great language for systems programming with support for multi-processing and object-oriented design, with some cool features like true closures and reflection.”

I was there when it happened, so regardless of the way go is being used and what it's being touted for now, in 2009-2011 it was all about Google's new systems programming language, set to replace both C and C++. And it was very clear that by "systems programming" Pike et. al meant any kind of job that was traditionally relegated to C/C++: http://www.informit.com/articles/article.aspx?p=1623555

Rust came out only slightly later and was also touted as a system programming language. From the the rivalry sprang out.

It turns out that Go's trade-offs and focuses (implementation simplicity, relative familiarity, static compilation, solid tooling, solid stdlib and easy concurrency) fit well for its eventual target demographics of web servers, networking and command line tools. These are all places where C/C++ had some foothold, but more often than not Go was replacing (or competing with) Ruby, Python or Node.

Rust, on the other hand, took over most of C++'s trade-offs and focuses (Zero-cost abstraction, expressive power and full control over memory management) while relatively neglecting I/O, tooling, ergonomics and the stdlib in the beginning. This attracted a very different crowd that looked to solve very different problems.

This.

People are move the goal post here.

Go has failed it's first goal. Rust hasn't.

But Go pivoted, and succeeded at their new goal.

Not sure I quite understand the premise that there is a strict delineation between programmers who are "prepared to accept more complex syntax and semantics for <...>" and otherwise. I can think of a lot of cases where I'd personally use either or (I've been looking into tikv contrasting it with cockroachdb's storage layer for e.g.), a lot of cases where I've used Rust's formalization of ownership/borrowing semantics to alleviate GC pressure in Go code. I'm hard pressed to find projects "for" Go that Rust wouldn't be a reasonable alternative to, and vice-versa.