Hacker News new | ask | show | jobs
by ilovecaching 2797 days ago
Woah, woah, woah. First, Go and C++ are vastly different languages. Apples and oranges.

C++ is huge. It takes an incredible amount of effort to become a proficient C++ developer, and even then, C++ offers none of the amazing safety guarantees that Rust's borrow checker enforces. It's old language with sedimentary layers, including C backwards compatibility. Rust is no where near as complex, and Rust does 5x more to ensure you use Rust correctly. It has brought so many crucial advancements as well: immutable by default, typeclasses instead of OOP (thank god), real sum types, better unicode support, better concurrency primitives, and much much much better tooling and package management. No one in their right mind would be cracking out another C++ project if they took the time to learn Rust and C++.

Go isn't really in the same league as Rust, C++, or C. It's syntax is deceptively C like, and it has an equally poor type system, but it's performance is closer to Java, which is a few orders of magnitude slower than C++. Despite pushing outdated concepts like null and raw pointers on to the programmer, it has a runtime with a stop the world GC with no guarantees about object placement on the stack or heap. Go is also incredibly divisive, it's a step backwards that hardcodes a few useful container types, and gives you no facility to create your own. It has a hard coded method of concurrency (goroutines). While useful in it's simplicity, it lacks the generality one would expect of an industrial language, and these concerns are only now being accepted by the Go team in their 2.0 drafts. Many people believe that Go rose to popularity because of the authors and the company sponsoring it, not on its technical merits ,and Brad Fitzpatrick, one of the maintainers, even said the language brought nothing new to the table aside from better concurrency support in the Gotime podcast episode he attended.

4 comments

> Many people believe that Go rose to popularity because of the authors and the company sponsoring it, not on its technical merits

I don't believe this to be the popular opinion. Originally Google's involvement dissuaded me, and indeed the very Googly bits have been the worst (context.Context), but the rest of it is markedly un-google-like. It's much more of a Bell Labs feel, with a focus on tool efficiency and stability.

> Brad Fitzpatrick, one of the maintainers, even said the language brought nothing new to the table aside from better concurrency support in the Gotime podcast episode he attended.

I think that was very much the intent. There were a lot of good ideas over the years (especially in Plan 9) and Go is really just a modern, polished revision of those ideas glued together.

Go is a _systems_ language at heart. It focuses on maintainability and literacy, and that's where it leads the pack in my eyes. It's possible to squeeze pretty phenomenal performance out of such a simple language. It's easy to drop into assembly for ultimate optimizations.

Perhaps generality is a mistake? I don't miss it. I've never found joy in debugging someone else's generalized metaprogramming.

Building software at serious scale has led me to appreciate the wisdom buried within Go. It's boring and I love it.

I've written a bit of Rust (and a lot of C++) which I find enjoyable enough, but they're tools I rarely find myself reaching for.

> There were a lot of good ideas over the years (especially in Plan 9) and Go is really just a modern, polished revision of those ideas glued together.

Plan 9 is an operating system. If you're referring to goroutines, CSP is completely unrelated to any of the work done at Bell Labs. That was Hoare. Go also kept a ton of terrible ideas, like nil, void (interface{}), and default mutability.

> Go is a _systems_ language at heart.

It really bothers me when people say this, because it's just untrue regurgitation from the Go team. It's not a systems language. It's a language that's pretty good for small web services. It has expensive interop (Solomon Hykes commented on this during one of his Gotime interviews) with C (even the Go team says cgo is not Go).

> It's easy to drop into assembly for ultimate optimizations.

You can only drop down into Plan 9 assembler, which is essentially useless. Write me an SGX lib without cgo in x86 and you can make that claim.

A lot of your claims about Go are false.

> It's a language that's pretty good for small web services.

I know projects in production running HUGE web services written in Go serving millions of reqs/s. If that's small for you then I don't know what large is. Look at techempower benchmarks[1] and additionally compare the source of actix-raw (Rust) to fasthttp (Go).

OS written in Go: In experiments comparing nearly identical system call, page fault, and context switch code paths written in Go and C, the Go version was 5% to 15% slower.

Read the paper[2]

1. https://www.techempower.com/benchmarks/#section=data-r16&hw=...

2. https://www.usenix.org/system/files/osdi18-cutler.pdf

People are doing OS research in Go, and Fuchsia core components like the TCP/IP stack are written in it, regardless of what the HN crowd thinks where Go should be used.

https://github.com/mit-pdos/biscuit

https://github.com/ycoroneos/G.E.R.T

Last version of Plan 9 was actually Inferno, which HNers keep forgetting about, which used Limbo for userspace code.

Limbo uses the channel syntax later adopted by Go.

People do os research in c#
And hopefully in the future even more so.

I was quite disappointed how WinDev managed to sink Longhorn and later WP 7.

+1 for Biscuit and Fuchsia
> but it's performance is closer to Java, which is a few orders of magnitude slower than C++

A few order of magnitude is an exaggeration. A more reasonable expectation is a 5x slowdown [1]. Depending on your task, a few orders of magnitude can be correct for JVM based languages; they can have very poor startup times (compared to c++) [2]. However, in startup time, go is not similar to Java.

[1]:https://benchmarksgame-team.pages.debian.net/benchmarksgame/... [2]:https://github.com/bdrung/startup-time

> JVM based languages; they can have very poor startup times (compared to c++) [2]

Hello world :-)

And is 54.55 ms perceptable?

(310.81 ms should be).

> And is 54.55 ms perceptable?

Its probably noticeable compared to instantaneously in terms of "feeling" different due to lag. However, it is definitely perceptible in the terminal based on my testing using `sleep`. For me (on my computer + monitor) down to 25ms is noticeable.

Also importantly, the hello world test shows 2 orders of magnitude simply, but the problem for JVM based languages gets worse for large projects (though not proportionally worse). Real java projects can take a second to launch whereas I haven't worked on a project large enough for that to be true in C++, Go or Rust.

"The basic advice regarding response times has been about the same for thirty years :

0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result."

https://www.nngroup.com/articles/response-times-3-important-...

Originally you asked "is 54.55 ms perceptable?", I say yes. I can tell the difference between 25 ms and 1 ms in my terminal.

That said, I don't think it is worth trying to reduce your startup time to the point where you can't tell the computer took time. Getting "the user [to] feel that the system is reacting instantaneously" is a different and more important goal.

> I can tell the difference between 25 ms and 1 ms

Maybe you are fooling yourself.

> Real java projects …

Can take much longer, and are engineered so that users don't experience a delay.

The users interact with a system that is already launched and up-to-speed. So much for Hello world!

I was just trying to come up with a real situation where there is a 2 order of magnitude difference.

Obviously in many situations you can mitigate the startup time. However, it does lock Java out of being a good replacement for git or other quick command line tools.

Not if jgit is already launched and sitting around waiting for commands.
> Go isn't really in the same league as Rust, C++, or C. It's syntax is deceptively C like, and it has an equally poor type system, but it's performance is closer to Java, which is a few orders of magnitude slower than C++. Despite pushing outdated concepts like null and raw pointers on to the programmer, it has a runtime with a stop the world GC with no guarantees about object placement on the stack or heap

Man, stating your opinions as fact is one thing, but every other claim you made above is empirically incorrect. Rust is a fantastic language on its own merits; no need to make stuff up about “the competition”.

> it's performance is closer to Java

Go vs Java https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

Go vs C++ https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

> pushing outdated concepts like null and raw pointers on to the programmer

I mean this is just a fact. Are you disputing nil and *?

> it has a runtime with a stop the world GC

https://blog.golang.org/ismmkeynote

"On the Y axis we have GC latency in milliseconds. On the X axis we have time. Each of the points is a stop the world pause time during that GC. "

> with no guarantees about object placement on the stack or heap

From the F.A.Q.

" How do I know whether a variable is allocated on the heap or the stack?

From a correctness standpoint, you don't need to know. Each variable in Go exists as long as there are references to it. The storage location chosen by the implementation is irrelevant to the semantics of the language."

> but every other claim you made above is empirically incorrect.

Seems you're empirically incorrect.

The benchmarks game is just that: a game. Notably, Go programs are prohibited from doing certain optimizations that are permissible for C++ programs. The conventional wisdom is that Go and Java are within the same order of magnitude as C++ though still slower. I’d accept that they are a full order slower, but not multiple orders.

> Do you dispute nil and *

I dispute that Go’s pointer is a “raw pointer” in any meaningful sense of the word. In C++, raw pointers may be uninitialized, they may be cast from any int, they don’t imply any automatic cleanup of the pointee, and they are subject to pointer arithmetic—none of this is possible with Go pointers except via the “unsafe” package. So basically none of the criticism of raw pointers applies to Go pointers.

> Go has a stop the world GC

You are correct here, Go has a stw GC. It’s probably not suitable for RTOS, but its pauses are on the order of microseconds, so most of the conventional GC criticism doesn’t apply.

> Stack vs heap

The language doesn’t have semantics for stack vs heap allocation, but that doesn’t mean it’s hard to control where things are allocated. In particular, the compiler can spit out where its allocating and you can adjust accordingly. It’s far easier to do this in the hot path than to have to specify where every piece of memory is allocated across your program.

> seems like you’re empirically incorrect

Quite the opposite, actually. There’s nothing wrong with not knowing or being mistaken, but there’s no need for overt snarkiness.

> The benchmarks game is just that: a game.

The name "benchmarks game" signifies nothing more than the fact that programmers contribute programs that compete (but try to remain comparable) for fun not money.

It's what you make of it.

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

> Go programs are prohibited from doing certain optimizations that are permissible for C++ programs

Which programs? Which "certain optimizations"?

That benchmarks game quote supports my point (not sure if you quoted it to contradict me or not?). As for prohibited optimizations, arena allocation is the one that comes to mind since it’s the standard way to avoid O(n) allocs.
> That benchmarks game quote supports my point…

As-long-as your point was not intended to be dismissive in any way.

> prohibited optimizations

Go programs are not prohibited from using arena allocation provided by a generally available library — that is what the C++ programs do.

Unfortunately there doesn't seem to be a generally available Go library that provides arena allocation. Of course, Go does provide GC.

> … it's performance is closer to Java …

You seem to be quoting yourself out-of-context ;-)

In full, you wrote — "… but it's performance is closer to Java, which is a few orders of magnitude slower than C++" — and that is not shown by those measurements.

>First, Go and C++ are vastly different languages.

Yes, the point isn't to say that they are similar. Quite the contrary in fact, they are different enough that they compliment well. If I have to do latency sensitive systems work I would use C++17. It's good enough, has useful constructs, and all-in-all, rather easy to write.

It's nice to have stronger static safety but they usually displace the cost somewhere else. AFAIK, Rust becomes extremely touchy when you start inter-operating with abstractions the borrow-checker is not omniscient about. Wrapping code in unsafe{} everywhere feels clunky. That's not my biggest peeve though. Programming complex systems is an iterative process for me. I prototype, go back, throw it away, rewrite, until requirements are met and so on. I don't feel like I would be productive doing that in Rust. I don't care for safety for as long as the software prototype is complete enough. In that phase of development, what I care about is a compromise between velocity, performance, and safety.

The only thing I really miss in C++ is powerful type-system: GADTs and all. But again, if I find that I need those I would use a language that truly excels at that, OCaml.

For anything else, I found Golang to be a terrific fit.

It is easy to on-board new people and have them get productive and feel empowered enough to push change. The building blocks are easy and compose well.

Yes, I agree the lacks generics of generics can be frustrating, especially when software grows. On the other hand, it can get old really fast to debug templated software.

As for GC, it might not use fancy algorithms but from empirical experience, having worked with a wide-range of different applications with different workloads, I found that GC pauses are short and hardly ever an issue. I wouldn't use to write a RTOS but for most usage it's fine and a net positive in productivity and quality.

>Go rose to popularity because of the authors and the company sponsoring it, not on its technical merits

It rose to popularity because it fills a huge niche. My job is to build robust systems that do their job and deliver business value. It's easy to maintain Go code, it's easy to understand, and provides the right amount of static safety most of the time. I find Golang to be a humble and honest language, a productive C.

Rust is cool but not worth it for me.

>No one in their right mind would be cracking out another C++ project if they took the time to learn Rust and C++.

If I had a dollar every time I had read that (replace Rust by Haskell/Erlang/Lisp/Whatever language the cool hip kids use).