There is no such thing as perfect language and clearly some languages are designed to be better at some scenarios than some other languages...and visa versa. The problem with Go is that it's designed to be a boring language where it's aims are more around language simplicity and API stability. This makes it very easy to play the "death by a thousand paper cuts" game with Go. If you'd believe what you read on HN, nobody would be using it when actually it is a very popular language.
[1] I'm sure that comment will annoy a great many on here but that's my honest observation.
I've used C (closer to Go than Rust) and I've used C++ (closer to Rust than Go) in previous jobs. My experience is that the C programmers tend to focus on the problem at hand. On C++ teams, people spend a lot of time going to C++ conferences and discussing the idiomatic approach to mundane tasks in their superior language. I imagine we'll see the same thing happen in Go and Rust... different personalities are drawn to the different languages.
I'd rather be going to security, networking and crypto conferences instead of wasting a lot of time on a particular language.
The only thing that doesn't exist is a C conference, but that's because C is the least common denominator.
Pretty sure that there are Go conferences.
CFPs are open until end of June. https://papercall.io/gophercon-au-2019
You can say that about any technical option that isn't garbage. That observation doesn't help us learn about Go, and doesn't let us dismiss all the other arguments.
If he or she wants a technical arguments for why they should or shouldn't use Go (which is a subtly different question but results in a significantly different answer) then there is already a wealth of debate on that topic already so there's no new technical perspectives that I - nor anybody else - could actually add.
Go uses multi-word primitive values, which means assignments are not atomic. Consequently, racing assignment statements can leave objects in weird states that violate type and gc invariants. For example, racing assignments to a value of interface type can give you an object with the wrong dictionary for its data.
The argument for not worrying about this is that this is an unlikely scenario. It's reasonable to think in probabilistic terms when clients are not trying to break the software (eg, in games or office software). However, attackers are not probabilistic: they actively search out vulnerabilities and push on them, so potential vulnerabilities turn into actual vulnerabilities in predictable fashion.
Rust also lets you write memory unsafe multithreaded code, if you want to.
That's a false equivalence. Nobody is criticizing Go for having an `unsafe` package. The criticism is that your Go code can be undefined without using the `unsafe` package. In Rust, you need to use `unsafe` in order to write code that has data races. Otherwise, data races are statically prevented in safe code, unlike in Go.
The situation with Go is pretty clear. Channels are safe. If you start mutating shared state across different goroutines, then you’re in the same situation you’d be in if you were doing the same thing in C++. Anyone who doesn't understand why that's potentially unsafe wouldn't be ready for Rust in any case.
Sigh. That's true of Go too. Both Rust and Go have `unsafe` labels that give access to dangerous things that can cause UB. Both Rust and Go are susceptible to UB-at-a-distance if library code internally uses `unsafe` incorrectly. The difference is that, in Go, you can write code with data races without using any `unsafe` at all. Nothing will yell at you (unless you exercise the race in a test and run the race detector). Rust does not suffer from this flaw.
I've been writing both Rust and Go since before each had their 1.0 release, and I like both languages. This isn't some back-handed comment about how I think Go is bad because of this. I rarely trip over data race related bugs in Go, but they do happen, so they aren't a huge issue in practice. (And your continued mention of channels is a red herring. Go has mutexes and idiomatic code uses mutexes quite frequently. Channels are not always the right thing to use.) Nevertheless, the comments here comparing Rust and Go are a fairly important mischaracterization of how each language treats memory safety, and it's important therefore to correct that.
Yes I know. I'm not sure why you think I'm saying that this is not true of Go.
>The difference is that, in Go, you can write code with data races without using any `unsafe` at all
Again, I know. I addressed this in my previous comment.
Less sighing, more reading!
> Anyone who doesn't understand why that's potentially unsafe wouldn't be ready for Rust in any case.
That's most certainly not true. They might not be ready to write high performance generic data structures from scratch, but application level code in Rust generally has about as much explicit `unsafe` as application level Go code, in my experience. (And writing high performance generic data structures isn't really a thing in Go. Not nearly as much as in Rust anyway.)
I'm confused by the second paragraph of your response. My point was that the lack of an explicit 'unsafe' block in Go isn’t that much of an issue, as pretty much everyone knows that Go does not make any memory safety guarantee when accessing shared state from different Goroutines. Anyone who doesn’t know this isn’t ready to get their head around writing multithreaded code in Rust. Rust’s features for doing this are cool, but they require a pretty good understanding of Rust’s complex type and lifetime system.
> Anyone who doesn’t know this isn’t ready to get their head around writing multithreaded code in Rust.
Well, if they aren't using `unsafe` in the process (or, to be fair, relying on buggy library code that uses `unsafe` inappropriately), they're not going to introduce memory unsafety via data races - no matter how "ready" they are. You just can't say the same about C/C++. Or even Go.
I think the point here is that if the word "unsafe" exists as a language construct, someone is not wrong in assuming anything without that mark is safe. Otherwise, why isn't there a "safe" language construct?