The title should have been: "C++11 or Rust? We chose Rust". In a greenfield project like this one seems to be, it's I choice I would approve.
A personal note regarding future comments to this thread: I have had enough of negative advertising against Go in every language related thread. People who use Go are not stupid: they know the language limits and tradeoffs and are okay with them. Deal with it.
FWIW: I've been coding in Go for a few years now, for me and (perhaps more importantly) the kind of projects I choose to use it for, the build tools have been more than adequate.
As with many things: it ultimately depends on what you're wanting to do, and what your expectations are.
These are the areas I think Go is most suited to, currently — and they've all been a breeze to implement/test/deploy/maintain.
It should be distributed along with the rest of the tooling in the coming months!
- Benchmark / profiling are much better ( https://blog.golang.org/profiling-go-programs )
- go fmt / go vet
- go doc
All of that that is supported by default by the Go team on all platforms, meaning it works well and I don't have to worry of using a 3rd party Cargo package.
Compile speed is certainly a thing go is excellent at. Cross-compiling, Rust is almost as good, but not quite yet, working on it!
Benchmark stuff is not yet stable, but for profiling, you don't need a special tool for Rust; all the C and C++ tooling works.
fmt/vet is rustfmt and clippy, which work today, and soon will be distributed with Rust tool.
rustdoc already ships with Rust.
So, my takeaway is mostly, needs some polish and shipping with the compiler. Thanks!
rustfmt (will be coming with rustc soon)
> - go doc
rustdoc (comes with rustc)
I've been learning Rust over the past months and I don't think the borrow checker stuff is as scary as people make it sound, match is amazing, so are traits, enums, cargo....
But, I can't, for the life of me, wrap my head around Rust's "concurrency" story. Yet.
Go concurrency is as close to trivial as one can get - channels, goroutines, select. That's it. And they compose nicely. I was doing concurrent networking stuff in a matter of days.
Rust has channels, select (kind-of?), but then I discovered it has futures, and something called "mio", and now something called "tokio", also read something about generators and coroutines, saw that C#-like "async/await" stuff is also being worked on, and I'm not sure how these things interact with each other.
I get the .NET async/await story, and always felt it was (good) syntactic sugar on top of "raw" JS-style futures, but how do all of them play with the CSP-style stuff like channels that's in the std. lib already? Is one being deprecated?
I feel in general Go's CSP model is more "powerful" and more "generic" than futures - you can even emulate futures/promises with Go's primitives, but I don't see how you can do what I do in Go with bare futures - "streaming" type stuff is especially hard with the futures' "all-or-nothing" approach.
I think Rust really nailed down the "one-thing-at-a-time" story - the docs, tutorials - all great. But for me it broke down quickly on the "easy concurrency" end - and maybe it's just a question of better tutorials/docs?
Yeah, so this is basically the result of two things:
1. Rust-the-language focused on making concurrency safe, and getting primtives right
2. The higher-level aspects of the story are still shaking out.
The core primitives are very simple: Sync and Send, two traits which let you declare invariants. But most people don't want to be programming with primitives. So there's been a lot of iteration on what a higher-level story looks like. There are a ton of options, and we've been iterating through them to figure it out. The stuff you're seeing is the result of that process, so you're seeing how the sausage is made, which can definitely be confusing. It's all under active work, and then, once the pieces are in place, getting the right docs/tutorials there.
So, yes. Thanks. It's a good reminder. We'll get there :)
One last thing, as a small amount of food for thought:
> I feel in general Go's CSP model is more "powerful" and more "generic" than futures
In some senses, yes, but they also come with tradeoffs, like any technical choice. Specifically, in order to do concurrency this way, you must go with green threads. And green threads lead to smaller stacks, which leads to non-zero cost of calling into C code, which is a drawback that Rust can't sustain. It works great for Go, but can't really work in Rust, generally. I mean, you can do it, yes, but that drawback doesn't work for the majority of our audience.
It's these kinds of tricky, in-the-weeds stuff that makes designs hard and take time.
People advocate against Go partly because they'd rather not have to work on Go codebases in future.
HN is not a very understanding place...
To a lesser extent the same is true of Rustaceans - they tend to be well aware of the constraints of their language, and won't try to defend it or pump it outside of some specific use cases. Nor do the Rust designers who are fairly humble.
Nobody should be calling Go users stupid. But they typically don't. At least not here. The language itself, on the other hand ...
Everything is a compiler exception. Nothing makes sense. Nothing.
The absolute worst in Go, in my opinion, is the "range" function/special case. It is return-type polymorphic. That's right, it does different things depending on what you assign it's result to (not even C++ dared to go there). Not parameter polymorphic, return type polymorphic. "Assign" a range to one variable, does X, two variables, does Y, nothing ? does something else yet again, channel ? Again something else and all of these are special cases in the type system (same -but not quite the same, of course- with case, channels and dicts, by the way)
Needless to say, even though you have to assign ranges to things in Go, that's the only way to use it, that assignment does something entirely different from any other assignment in Go's type system.
Go is how to make a language extremely dumb and yet make have a type system that can't be (fully) described shorter than Haskell's.
Most Go programs could have been written in Java, Scala, C# or Kotlin and been shorter, more predictable and probably faster. Certainly more maintainable (ok maybe not for Scala).
for k := range map { }
is the same thing as for k, _ := range map { }
Would requiring the second version instead of the first actually be that much of an improvement?The only true return-type polymorphism is type assertions, which is reasonable in my mind cause I don't think ignoring the "assertion failed" should ever be a logical thing to do.
1) for k := range list {}
2) for k, i := range list {}
In python, the equivalents are: 1) for x in lst:
2) for x, y in enumerate(lst):
So are these "the same" ? No. for index := range list {}
and for index, value := range list {}
Yes, these 2 version do perform very similarly, you are just ignoring the second return value in the first version, i.e.: for index, _ := range list {}I was never good at computer science-y "language theory" type stuff. I believe you when you say that Haskell or Forth are better languages - I just can't use them worth a damn.
Go is a practical language for me - it's not beautiful, or elegant, the type system is only 70% there, can be verbose, etc, etc, but it allows me to put my code in production and have a very high level of confidence that I won't get a phone call at 4 am. I don't have that confidence with Ruby, or Python, or Javascript.
I find that Go is very easy to pick up, and hard to really fuck up. Most people at my company can read my code and I can read theirs, which is mind-boggling to me. Go somehow achieved what I thought was impossible - to read and grok quickly other people's code.
Go sees was developed by "engineer" types - not "language nerds". And, yes, it shows.
FWIW, I also love Rust and C, but will choose Go over Rust any day when my productivity and dead-lines are more important than close-to-C performance.
=)
But it does have generics - maps, channels, slices! What more do you need, man!?
Can’t call into c as fast Has micro gc pauses which effect performance Doesn’t give me explicit control of the hardware
Go is great for middleware but he authors go it right