30 ms·
Why Go and Not Rust? (2019)
- mgomez 4y agoPrevious discussion: Why Go and Not Rust? - https://news.ycombinator.com/item?id=20983922 https://news.ycombinator.com/item?id=20983922 - September 2019 (477 comments)
- teddyh 4y ago“Why Google and not the Mozilla Foundation?”
- steveklabnik 4y agoThe Mozilla Foundation has had very very little to do with Rust. When members of the Rust team was employed by Mozilla, that was the Corporation, not the Foundation. And nowadays there’s even more separation between the two.
- teddyh 4y ago> The Mozilla Foundation has had very very little to do with Rust. When members of the Rust team was employed by Mozilla, that was the Corporation, not the Foundation. I stand corrected. > And nowadays there’s even more separation between the two. That is almost entirely irrelevant. A project’s culture is about 90% the culture of its initial group. Even if Go(Lang) would be transferred and entirely sponsored by, say, the EFF or something, I would still not trust the language to be a good fit for the wider community.
- pcwalton 4y ago> A project’s culture is about 90% the culture of its initial group. Eh, not in the case of Rust. Rust doesn't even use the MPL. The biggest Mozilla-ism I can think of that remains in the Rust project is, like, the use of "r+" or "r=me" for code reviews.
- recursivedoubts 4y agogarbage collection. sorted
- nine_k 4y agoWhy Lego and not 3D printing? Why a pizza and not a restaurant meal? Why a scooter and not a skateboard? A different set of tradeoffs. Sometimes one wants a limited but easy thing instead of a powerful thing that requires significant mastery to handle.
- kjksf 4y agoName a program you can write in Rust that I can't write in Go. Both Go and Rust and general purpose languages. You can write most (but not all) kinds of software in both of them so a claim that Go is more "limited" than Go is bs. As to "mastery": I've spent significant amount of time mastering C++ and got pretty good at it. Go was both significantly easier to master and I'm significantly more productive in Go. So what exactly is the justification for C++ (and Rust) complexity?
- Tanjreeve 4y agoDefinitely not: Anything where latency matters and there are real performance memory constraints. GC is a show stopper for anything high performamce or databases etc. Doing it the hard way: anything with a complex domain e.g geospatial applications where you have an exponential explosion of different logics for different types of shapes or modelling medical ontologies. You can write anything in any language the issue is if you're taking the path of least resistance to do it and how much risk you're exposing yourself too with variable skill levels of developers doing it. E.g see all the frankenpython implementations kicking around banks and Instagram to use the "simple" language that turns into something much more complex and brittle.
- pjmlp 4y agoAn OS boot loader.
- shaunsingh0207 4y ago> Name a program you can write in Rust that I can't write in Go Name a program you can write in <language> that I can't write in <language> is a terrible way to compare languages. That applies for any Turing complete language, but I wouldn't write a game in emacs lisp. > Go is more "limited" than Go Assuming you mean "go is more 'limited' than rust, you can write all software in both languages. I'm not sure who claimed it either because both the linked article and comment above you don't. The justification for C++/Rust is largely the same as the justification for any lower level language: performance. Theres a lot of cases where GC pauses are a no go (pun intended). Well written rust is going to be more performant than well written go. You have greater control over threads, for better or for worse. The benefit of rust in particular is the approach to memory management, package management, and how hard rust it is to shoot yourself in the foot. Rust filled a gap where people wanted a performant, expressive low level language without the memory hassle that came with c/c++.
- verdagon 4y agoA rarely covered topic in these discussions is architectural benefits that Go provides. Rust tends to solve problems by adding more constraints, which often leads to more complexity. It's great when that complexity is inherent (like with static typing), but quite painful when the complexity is artificial/incidental. In the domains I work in, the healthier approach is usually to decouple more, rather than add more constraints. For example, in Rust, we often have to use an index or an ID where a regular reference would do in Go. We need to do extra refactoring of function signatures to pass collections down the call stack so we can then use that index/ID... and then find we can't modify a function signature because it's a trait override, and resort to tricky workarounds. In Go, we just use a reference. That choice is decoupled from memory concerns. Another example is that in Rust, we often need to refactor to add `async` keywords to callers (and their callers) and run into the same problem. Go decouples all that coloring away. Another example is how Go interfaces are structural, which further decouples a caller from a callee. Hillel Wayne had a stellar article on how constraints lead to complexity: https://www.hillelwayne.com/post/complexity-constraints/ https://www.hillelwayne.com/post/complexity-constraints/ Go is designed to decouple away details that are unimportant for the vast majority of domains. That means a codebase can change faster, require less refactoring, and generally be healthier in an architectural sense. That isn't saying that Rust is bad. It's amazing for embedded programming, it's much faster for some domains, and it doesn't have some of Go's other nonsense like nil and how their defer isn't block-scoped. But one can't discount Go's architectural benefits, especially when starting a new project that will be worked on by a large team. Just my two cents, reasonable opinions may differ =)
- jayd16 4y agoI do wonder how this decoupling works for GUI dev where you need to explicitly juggle main thread and background work.
- gtowey 4y ago> especially when starting a new project that will be worked on by a large team. This alone is what makes me love go. It makes working with a team on shared code less of a hassle than any other language I've used. To me, that's worth more than nearly any amount of language features you could name.
- phillipcarter 4y agoHoo boy, this article is pretty wild. > Go is faster than Java / C#, more memory-efficient than Java / C# This is probably the worst part of it, because it doesn't substantiate any of these claims. Look up any set of benchmarks online and you'll find this claim to be mixed at best. Suffice to say if performance actually matters for your app, you'll squeeze plenty out of C# and Java just as you can with Go. And all three languages have no shortage of pitfalls for performance if you're not careful. Go is just a different language. And the author liked it more when they wrote this in 2019.
- kristoff_it 4y agoI actually clarify right after that my claim has nothing to do with benchmarks and actual performance of the programming language. > Go is simple so that all of this can hold true when confronting the average Go program with the average Java / C# program. It doesn’t matter whether Go is truly faster than C# or Java in an absolute sense. The average Java / C# application will be very different than the best theoretical program, and the amount of foot guns in those languages is huge compared to Go. Not to say that I knew perfectly well where Go sat vs Java vs C# in terms of raw performance, but mine was a different point based on my experience.
- phillipcarter 4y agoWhat you're highlighting is also unsubstantiated. What is an average Go, C#, or Java program? I've certainly spoken with C# developers who find even moderate combinations of error states too confusing to handle in Go since it lacks abstractions necessary to represent those states. And I've met Go developers who get horribly confused by overabstraction in C# programs where you need to chase down code across many different files just to know that A called B. But I don't think I could make any blanket claim about simplicity and how that impacts performance. The only thing I do know for certain is that performance work is hard, and all three languages come with toolkits to help you manage it.
- mtlynch 4y ago>>Go is faster than Java / C#, more memory-efficient than Java / C# >Look up any set of benchmarks online and you'll find this claim to be mixed at best. I don't know a ton about low level performance, but I'd find it surprising if it's not true. How can interpreted bytecode outperform direct machine instructions? The benchmarks I've found have Go outperforming Java and C# in almost every test. https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/go.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
- why-el 4y agoGolang runs some pretty serious software (docker, K8s, stuff at google, hashicorp, etc, all software that's functional and makes money). Rust is kinda the same, but not there yet, it has some benefits that are yet to materialize, but so is so much software out there. Does it matter? No, learning either will make you a better programmer. Learning either and NOT forming a strong opinion? you will be a saint and forever remembered.
- stouset 4y ago> This makes Go easy to learn and, even more importantly, it ensures that Go projects remain understandable even when growing in size. Do people actually find this to be true? Honest question. In my personal experience, as Go programs grow in size, they become increasingly unmaintainable. Avoiding abstraction and keeping everything explicit sounds great in theory, but what actually happens in a larger project is that they just become a mess. Functions start taking on seemingly-unrelated extra parameters just to shove a tiny bit of extra necessary information four layers down. Details related to one coherent idea are strewn about everywhere because it was easier to add the logic in situ to a dozen places rather than have one part of the code responsible for it. Internal idioms are copy-pasted across dozens of files, many of them missing improvements made to later copies. I've seen this happen in every large go project I've jumped into, and it (subjectively to me) seems to be significantly worse than in other languages. Maybe it's because—on average—gophers tend to trend more junior in their careers and there haven't been enough senior mentors keeping things well-factored. But at this point it makes me instinctively dread any time I have to switch to a new project that's written in the language. The whole "complexity is bad, explicit is good" mindset vaguely reminds me in some way of the hype around "schemaless" databases. No database is schemaless. All this means is that you still have a schema, it's just implicit, inconsistent, and now you lack tools to understand and/or manipulate it. The complexity in your go program still exists, it's just scattered absolutely everywhere and you lack good tools to wrangle the worst parts of it.
- simoncion 4y agoI don't find this to be true. Go projects of a particular size are generally more comprehensible than Ruby projects of the same size, but that's _only_ because Go uses explicitly-declared typing. Large Ruby projects and large Go projects are both pretty terrible to try to understand.
- bryanlarsen 4y agoLarge Ruby projects are by the far the worst in my experience, far worse than Python, Java, C++, or JavaScript. So if Go is just as bad as Ruby than IMO you are agreeing with the parent, not disagreeing. Of course team quality matters much more than language choice, so my experience will differ from others.
- Havoc 4y agoBoth strong contenders but rust in kernel and rust being better placed for wasm sold it for me
- nouri 4y agoCurious what people think about using Go for a (distributed) database? For example CockroachDB seems to be mostly written in Go, while YugabyteDB is C/C++. Would Go give an advantage to the CockroachDB project?
- ripley12 4y agoAs I understand it (heard second-hand from someone in the know), the CockroachDB people regret that language choice and that’s why Materialize (which employs a bunch of ex-Cockroach people) uses Rust. I generally think a garbage collector makes sense for 99% of programs out there, but databases often need a bit more control over memory management for performance reasons.
- jordanlewis 4y agoI've worked on CockroachDB for almost 7 years as both an engineer and in management. We do not regret writing the database in Go, in my opinion there is no way we would have been nearly as productive if we wrote the entire thing in Rust. There are many parts to a distributed database, and there is surprisingly more business logic than you might expect. The business logic is mostly what I am talking about - being able to develop quickly in Go for these less performance sensitive parts is a huge boon. For performance sensitive parts I think there's an argument that we could have been happier in a language like Rust, for example a dual process model like TiDB's. But I think it's ambiguous: a more complex architecture like that one comes with huge tradeoffs. tl;dr there's much more to database development than performance at all costs, and it's false that the team regrets using Go, please don't spread that rumor :)
- commitpizza 4y agoThe only reason why I would never use Go is because it is made of and controlled by Google. Maybe that is a stupid reason but I stand by it.
- speed_spread 4y agoThat's not stupid, that's wise. Go is designed by Google to solve Google technology and employment problems. There's an underlying philosophy that you buy into when you pick a language. Open languages will be upfront about their worldview. Go's raison d'être is more or less "make programmers expendable like soldiers on the front" but of course they never spell it out like that. They only market it out because they need a pool of fresh warm bodies to throw at their Google problems.
- kjksf 4y agoI wrote more Go programs that I can remember. I never worked at Google and presumably I don't have Google's problems and yet Go is the best language I found to wrote those programs. Simple, fast and productive. Could you connect the dots for me: what exactly is that Google needs that I don't and how does that map to design of Go? Is it compiled because only Google needs statically compiled, easily cross-compilable, easy to distribute executables? Is it portable to almost every OS / arch available because that's something only Google needs? Is it statically typed because only Google cares about catching type errors at compilation time? Is it garbage collected because only Google cares about the productivity and memory safety of programs? Which Go design features solve problems that only Google has?
- shaunsingh0207 4y agoCurrently googles problems might map well with your problems. The issue (and fear) is what if google's problems change in the future and don't line up with yours?
- 015a 4y agoThe Go vs Rust debate is really tiring. Beyond releasing around the same time, they're languages built for extremely different purposes. Instead, I'm going to lament about a few things I think would take Go from an extremely good language, to one of the best languages out there: * Context. Context-creep is really annoying; similar to async in JS, it becomes something that over time absorbs your codebase and dirties function signatures beyond recognition [1]. Unlike promises in JS; for surprisingly low benefit. I don't for sure know what a better solution looks like, but my initial thought: the language runtime should have globals like setContext() and getContext(), which can set and get a goroutine-local context. If you want to pass a context between goroutines, just do it like you'd do it today. * Enums. I will die on this hill: proper enums (think typescript and rust) are one of the most powerful programming paradigms in typed languages. Go not having them is one of its largest gaps; and leads to really weird obviously-should-be-an-enum things that instead get shoved into a set of constants with a common prefix [2]. What do you lose out on? So. Much. Beyond the obvious [3]; one of the coolest features of enum-prioritizing languages like Rust is exhaustive switch/casing; this is a huge feature in application development, and that's what Go is great at; except for this gap. * Pointer-to-interface shenanigans, and how that oftentimes interacts with custom error handling. This is the WILDEST part of Go, and I am convinced that even extremely seasoned Go devs run into this, know that it does happen, try to avoid it, but can't explain why it happens. "Oh yeah, uh, nil, when coalesced into an interface, is nil, but, uh, also isn't, uh, nil, uh, when it comes to, uh, checking if its nil" [4] WHAT. There's no excuse for this; this isn't a feature, this is a bug, end of story. Its a bug that, for some reason, has lasted years; in the same breath that defenders explain why it happens they also say "oh, but, Go is industrial scale, its for large engineering teams"; this is not industrial, this is brittle. [1] https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3 https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3 [2] https://pkg.go.dev/net/http#pkg-constants https://pkg.go.dev/net/http#pkg-constants [3] https://go.dev/play/p/mc-0m_fakfJ https://go.dev/play/p/mc-0m_fakfJ [4] https://go.dev/play/p/lIEmO9tG4iQ https://go.dev/play/p/lIEmO9tG4iQ
- jcrites 4y agoI haven’t written a lot of Go code, but I suspect I’d be extremely annoyed by its approach to error handling (as a result that requires explicit handling). In the vast majority of all Java programs that I have written, there is typically a single try/catch block at the very top level (and occasionally in low level IO code) - and none of the intermediate layers of application logic need to concern themselves with error handling (exception handling) at all. This is as it should be. The needless ceremony required to check and handle errors on every function call sounds tedious and I can’t see how it contributes to clarity. Try/catch is a blessing. Rust achieves a similar degree of ergonomics with its `Result` type and `?` operator. You can propagate the failure case of functions that return a result easily with `f()?;`. While it does require ‘annotating’ these functions by declaring them to return a `Result`, unlike Java, that explicitness fits well into Rust, and is trivial to compose using `?`. Instead of multiple if/then or match blocks, you can write `let x = foo()?.bar()?.baz()?` or similar. This also works with Rust’s `Option` type, and can be implemented for arbitrary types (as I understand it) using the `Try` trait. Simple monadic programming without the complexity present in other functional languages. And I haven’t even touched on the benefits of Rust macros. TDoes Go have anything like Rust’s `dbg!`, or its statically-typed `println!`, `format!`, etc.?
- pram 4y agoOne big thing for me is I'm actually able to maintain stuff I wrote, for a very long time. I made a Go application in version 1.5 and I've brought it up to 1.19 with very little changes. This thing is basically 'done' and its been running for the past 7 years with zero issues, with uptime usually going into a year+ On the contrary, most the Javascript I wrote in 2015 is essentially defunct. I've developed a deep dread for starting anything new in it.
- philosopher1234 4y agoI’m curious, what changes did you have to make to upgrade your go code?
- pram 4y agoThe two major ones were a JWT package being deprecated, and then adding go mod which didn’t exist when I started. Then some smaller go vet issues.
- dharmab 4y agoI recently converted some Go code from 1.13 to 1.19, and the bulk of the work was replacing vendored dependencies with go modules and updating the CI/CD pipelines to properly cache said modules.
- stevekemp 4y agoChanges I remember included updating ioutil.ReadFile() to be os.ReadFile(), and some other similar depreciations. I've noticed over time that the various linters and vet-tools have become more strict about things that they didn't detect in the past. But I tend to write code with reasonably high levels of coverage (in the 80-100% region) so running linters and test-cases has always been part of my approach to using go.
- Andys 4y agoIt also really helps having the ability for one Go program to use multiple versions of a package. Makes it easier when you come back to an old program with old dependencies and try to start working on it again.
- nicolaqua 4y agoGo and rust are both wonderful languages, but from a startup perspective the conclusion one will always reach is that go is more befitting of the vast majority of use cases than rust is. I feel like this business perspective is a little neglected, even though speed of iteration is the main consideration for most startups that are finding pmf. Go is simply more productive to write. Now, for things where performance or memory really matters, rust is beautiful and wonderful (and the language is very fun!). These use cases, like blockchain or specific algorithmic stuff, make rust a compelling choice - the new C++. But for rolling up your sleeves and getting stuff done quickly (aka shipping fast), go is an absolutely fantastic choice. Go seems to be as much as 50% faster to ship features based upon my unscientific observations. For what it’s worth, the only two languages our company uses for backend services are go and rust, so I love both languages (otherwise we’d be using other languages). I find rust to be particularly fun and interesting to code in, but for most microservices, go reigns supreme. It’s simple, readable, and nice generally (though error handling could use some work). For companies with a mature feature set, I’d imagine rust is highly preferable.
- kaba0 4y agoThe whole title doesn’t make sense - it’s like why JS and not C? There is no niche where you have to use a low-level language and you would go with go which is a managed language much closer to JS than rust.
- osigurdson 4y ago>> Go is faster than Java / C# This is not generally supported by benchmarks that I have seen (random link below). https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/go-csharpcore.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
- kjksf 4y agoBecause there are lies, damn lies and benchmarks. I looked at first benchmark (funkuch-redux) where C# significantly beats Go (8.3 vs 32). It turns out that the winning C# programs uses SSE2 intrinsics. The second best C# programs virtually ties with Go implementation, which is not a surprise: those are pretty straightforward, calculation heavy programs. Easy to optimize so both .NET JIT and Go compiler do similarly good job generating code. So all we've learned that using SSE2 can significantly speed up certain kinds of code but it has nothing to do with C# vs. Go. Arguably SSE2 intrinsics are actually part of C#. Apparently they were added as a library in .net core 3 (in 2019?). You will typically not use intrinsics in your code because a) you don't need them b) they're pain to use And I could write a Go version that uses intrinsics and it would be equally fast. The same applies to n-body and spectral-norm at which point I've lost interest in those benchmark because all they show is that someone spent extraordinary amount of time optimizing C# code with intrinsics while the same effort wasn't applied to Go programs. But by constructions you average Go program will be faster that your average .NET JITted program. JIT has constant overhead and can't spend as much time generating best machine code as offline Go compiler. Plus .NET is more memory hungry (.NET object have memory overhead not present in Go structs), UTF-16 strings take up ~2x more spaces than Go's byte strings etc. Doesn't mean every Go program will be faster than equivalent C# program but it's more 80% in favor of Go.
- osigurdson 4y agoI don't think I have ever seen a benchmark that concludes this. I think the best conclusion is that Go, C# and Java perform roughly the same - which makes sense since they are basically all the same thing. As you say, you could write a Go version which would be equally fast. Here is another showing Go under-performing both Java and C# by a bit. Benchmarks may not be perfect but better than conjecture. https://www.techempower.com/benchmarks/#section=data-r21 https://www.techempower.com/benchmarks/#section=data-r21
- osigurdson 4y ago>> The Go community regards as anti-patterns many abstractions regularly employed by Java / C#, like IoC containers, or OOP inheritance, for example. I really dislike this type of argument. It isn't the language itself that is better, it is the community. This article should just be called "I like Go better than other languages". It barely even discusses Rust or any of the truly unique things that Rust actually brings to the table vs the GC big 3 (Java, C# and Go).
- kjksf 4y agoCommunity (as used in this context) is a derivative of a language. The reason inheritance is not popular in Go is that it's not possible. The reason IOC containers are popular in Java and not Go is that Java makes them relatively easy and Go doesn't. Go is drastically less complicated language than Java, it has significantly less foot guns. As a result Go community self-selects to people who value simplicity and as a result you do get a different community. But community is shaped by the language so it really is about the language.
- deleted 4y ago[deleted]
- kaba0 4y ago> Go is drastically less complicated language than Java Is it? Java is a very bare-bones language, remarkably so given that it is 25 years old.
- sgt 4y agoThat may have been true up to Java 8, and regardless the JVM is definitely not bare-bones on its own.
- osigurdson 4y agoIt looks like IoC frameworks do exist for Go (https://github.com/alibaba/IOC-golang https://github.com/alibaba/IOC-golang for example). I'm sure the True Gosman would not use this but it exists nonetheless. It looks like there are some heretics in the community - how shall we exile these vile peoples?
- denysvitali 4y agoI love both languages, but find myself writing Go most of the time because of the speed of its compiler, the decreased cognitive effort (in Rust you have to think about lifetimes quite often) and the cross compilation / static build features. Sadly, I think I cannot use Rust to the fullest since the RLS (language server) is as slow as the compiler itself, and you find yourself waiting quite often to realize you made a mistake a couple of lines before the one you're typing. Let alone guessing the types and stuff because the compiler / RLS didn't catch up to what you wrote so far. I hope the speed of the Rust compiler / RLS will improve soon, it has been like this for the last 4 years :(
- timeon 4y ago> RLS will improve soon Isn't RLS deprecated for rust-analyzer already for some time?
- denysvitali 4y agoSorry. I'm referring to RLS as any language server implementation and not the specific RLS tool itself
- sgt 4y agoThe Go vs Rust debate rages on. Something to keep in mind is that Java 18+ is pretty good. I don't do as much Java as I used to, I mostly code Python on the backend, but if speed/scaling becomes an issue then Java could be a good alternative to Go for enterprise software, despite being considered "boring" by many.