Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Should I Rust or Should I Go? (kerkour.com)
106 points by cjg on Sept 15, 2023 | hide | past | favorite | 170 comments


As someone building my startup [0] on Rust (and a fan of the language since ~2014) I don't think this is a very compelling list of points.

> Rust is overhyped

People are excited about Rust! Not sure why this is a reason you _shouldn't_ use the language.

> Rust projects decay

The text doesn't match the headline here; Rust takes backwards compatibility very seriously, and rust code I wrote in 2016 against Rust 1.10 still compiles with Rust 1.72 in 2023.

> Rust is still in beta

Mentions missing async traits, which is legitimately annoying, but the workaround with the async_trait crate works in practice

> The standard library is anemic

This is a tradeoff; big standard libraries become graveyards over time (the classic article on this: https://leancrew.com/all-this/2012/04/where-modules-go-to-di...). How long was Python stuck with a terrible HTTP client because that was the one in the standard library? In Rust we have an incredible, state of the art regex library because it's a separate crate and is allowed to evolve.

> async is hard

Rust's async is hard to get started with; it's a barrier to get over like learning the borrow checker and lifetime system. But once you do I've found it productive and incredibly performant.

--

Overall, I don't think that Rust is the right solution to all problems. Rust makes you think about everything you're doing, the ways in which your programs use resources, and every possible class of errors. This is incredibly useful for writing fast and correct software, but will be overhead for people who just want to move fast.

I also think that static memory management is not the right tradeoff for most application software, although a GC language with Rust's ergonomics and crate ecosystem would be amazing for those use cases.

I'd personally always choose Java over Go especially given recent developments like ZGC, GraalVM, and Project Loom which essentially makes Java a better Go.

[0] https://arroyo.dev


>> Rust projects decay

> The text doesn't match the headline here; Rust takes backwards compatibility very seriously, and rust code I wrote in 2016 against Rust 1.10 still compiles with Rust 1.72 in 2023.

This hasn’t been my experience. Though it’s often not large changes that are needed. The bigger problem in my book is the crate ecosystem, which is riddled with abandonware. Though this issue plagues most all languages.


For all the praise cargo gets, the lack of namespaces seems like a pretty huge oversight :/


This is endlessly debated within the community (e.g., https://internals.rust-lang.org/t/blog-post-no-namespaces-in...), and there's no consensus on whether namespaces would be an improvement


There's no consensus mostly because namespace proponent, despite all the noise they make, haven't been able to articulate a constructed argument about what namespace is actually bringing to the table.

For instance, most of them bring typosquatting as a problem that namespaces solve, yet they completely ignore namespace typosquatting: for instance instead of typosquatting `ripgrep` with `rigrep`, you'd typosquat `burntsushi/ripgrep` with `bunrtsushi/ripgrep`…


> Rust makes you think about everything you're doing, the ways in which your programs use resources, and every possible class of errors. This is incredibly useful for writing fast and correct software, but will be overhead for people who just want to move fast.

I agree with the reduction in development speed. But the cognitive load is less, at least for me. Rust's type system, error handling primitives, language server and compiler messages seem to guide and reduce the effort needed to write good programs. The reduced development speed is often an acceptable compromise for all the advantages Rust gives - especially the cognitive load. The language also seems to save a lot of debugging time - so the reduced development speed may not be of much consequence.

> Overall, I don't think that Rust is the right solution to all problems.

I guess this depends on how comfortable you are with the language. Rust is my second choice after shell scripts to automate things. The point is, your statement is correct for only a class of developers - those who are new to Rust. For others, it's just as good as any other language for almost all problems.


> ZGC, GraalVM, and Project Loom which essentially makes Java a better Go.

GraalVM is still nowhere near as nice as Go when you need to compile quickly. Last time I checked, the compiler needed orders of magnitude more time and memory to make a binary. ZGC is pretty nice, though.


Why not Kotlin instead of Java? I feel Kotlin is very underrated.


"Rust makes you think about everything you're doing ... overhead for people who just want to move fast."

Honestly, I find it much easier to move fast in Rust because for explorative code, I just bang out the code and used copy/clone liberally and once I have a skeleton it's usually a few iteration until rustc agrees to compile my code. Strong types makes it very easy for me to move fast. Doing this in C/C++ never worked for me and I always had to be extra careful lest I'd end up wasting a lot of time debugging.

I don't think Rust is over-hyped; almost everything I would have used Haskell for I do in Rust now.


> I don't think Rust is over-hyped; almost everything I would have used Haskell for I do in Rust now.

As a Haskell fan this is very interesting! What sort of things do you write where you find Rust is a better fit? No code that I write in Haskell would be much better off without GC so I struggle to think of reasons Rust could be a better fit.


The _language_ isn't a vast advantage; the type system is near-identical (which is important). Both have their advantages, but the ecosystem (tools, crates, documentation, educational material, community) is so much better and richer in Rust, and of course wrt. performance and memory frugality, Haskell doesn't even compete. (I haven't never been able to use Haskell professionally because of that, but I use Rust for work now).

Something things about Haskell have always boggled my mind: integer overflows aren't caught (so much for safety) and the argument for this choice was performance, but at the same time, the default string type is a linked list of characters. In fact, Haskell relies far too much on lists. In Rust, the rough equivalent is Vec and Vec slices, which takes less memory, is much easier to parallelize, and is just much faster overall.

It is true that garbage collected languages allow more flexibility than languages with an ownership model (~ linear types), but so far I have been able to work with this and the end result usually benefits (I haven't had to use interior mutability yet).

Disclaimer: I'm neither a Haskell or Rust expert, but probably equally intermediate in both.


Good to know about the ecosystem differences, thanks. Hopefully with some effort Haskell will be able to catch up there. And yes, Haskell gets some defaults wrong.

Regarding the type systems, they're definitely not near identical :) Haskell's is far more powerful. Perhaps you mean "the type systems are near identical for the kinds of programs I write". Speaking for myself, I could never work without a straightforward implementation of higher-kinded types, for example.


Well, now you need to define "Haskell". Haskell 98 has effectively the same type system as Rust (ignoring lifetimes). GHC does not. I guess I'm not a fan of the overly abstract types in later GHCs.


Normally by "Haskell" I'd mean "GHC", since that's the Haskell that everyone actually uses, but even Haskell 98 has higher-kinded types!


Nim is another alternative. Fast to write and excellent performance. Needs a bigger community though.


In what world is Go more reliable or faster than Java? Especially modern Java (or other good JVM languages like Kotlin).

It compiles faster but that is about it. Which is a good thing too because it's verbose AF and heavily reliant on code generation even after generics shipped so that compiler lines/s actually matters.

The only knock you can put on Java for reliability is null-safety but lets be real, nil pointers, bad slice initalisation, etc are 10x worse in Go especially these days with @NotNull and powerful editors like IDEA stopping you from doing dumb things. Or simply using Kotlin which is non-nullable by default.

That and all the things Go is good at Java is simply better at. (especially once Java 21 ships in the next few days).

- Low pause GC? ZGC has Go beat, not just on pause times but on throughput and heap size scalability up into the terabytes. - Non-blocking code with synchronous coding style? Virtual Threads are much much better than goroutines. - Channels? ArrayDeque and friends are faster and have a lower learning curve.

Maybe the only area I think I prefer Go to JVM-land is the good parts of the stdlib. Go has lots of shit stdlib cough collections cough but there are some real gems. Namely the x509 and ASN.1 libraries are absolutely top notch.

Learning curve is also lower ofcourse, it's a very very simple language which is good for beginners and those taking their first steps out of JS/Ruby/Python into static types, pointers, etc.

Anyways, my real point was Java is easily faster and more reliable than Go and it seems pretty insane to reach the opposite conclusion if you have been on top of developments in both languages.


Go's GC is much more naive than modern Java GCs, and the codegen is not terrific.

That said: A few design decisions in the Java language (that are only slowly getting fixed) harm performance:

1. "Everything is virtually dispatched" reduces the ability to make inlining decisions sensibly. 2. Escape analysis gets harder (and less effective), leading to moving fewer variables onto the stack. 3. The poor support for allocating compound data types on the stack.

All of these conspire to create many more heap allocations than comparable Go code, so even if the GC is much better, the amount of work it has to do is much bigger.

Achieving any form of data locality in Java is also hard because it's really hard to nest structs.

The Java design shows that the memory wall wasn't a thing yet when the language was designed...

Things are slowly getting fixed, and there's a lot of interesting off-mainstream stuff that can be done to get more perf in Java-Land (Azuls JVM, Graals AoT etc) - but the strange thing is that Java does pay for some outdated design choices while Go performs pretty well despite a very simplistic implementation...


> "Everything is virtually dispatched" reduces the ability to make inlining decisions sensibly.

you can use "static" keyword?..

> Escape analysis gets harder (and less effective), leading to moving fewer variables onto the stack.

does go have the same idea of escape analysis with benefits and issues?..


Static == final?


static methods, they won't be virtually dispatchable, and will be potentially inlined.


That is a good point, but soulbadguy was pointing out that if you make a (non-static) method "final" then you can't override it in a subclass, which should have the same effect, without having to change the semantics by making the method "static".

That said, if there are no actual subclasses of a given class, the JVM will know that, and should be able to inline functions as necessary. That is complicated quite a bit by the fact there is no exhaustive list of which classes are available (the JVM only knows which classes it's seen), and that new classes can be added during the runtime (e.g. Tomcat will load a WAR at startup which will add new classes, or Maven might download a plugin and execute code). But if that _doesn't_ happen, i.e. you load a class and the JVM never sees a subclass and it decides to optimise that part of the code then it will inline what it can (and un-inline it if a subclass shows up later.)


I also read in internet that JVM inlines all method calls by default, and fallbacks to virtual dispatching if finds out it is needed.


> Java is easily faster and more reliable than Go

I work in Java for my day job and I disagree.

1. Cold starts for Java serverless (lambda) are worse than scripting languages

2. For everything else, Java uses 5-10x more memory than Go. The memory overhead difference is really noticeable while the CPU difference is often similar.


1. Ever thought about using class caches, AOT compilation e.g. OpenJ9, GraalVM,...?

2. Most of the time, a signal that the wrong algorithms and data structures are being used

Amazon isn't rushing to rewrite their infrastrure from Java into Go.


Why would they rush? Customer will ultimately pay for infrastructure not Amazon.


Hardly different from what many Go folks are paying as well.


> Cold starts for Java serverless (lambda) are worse than scripting languages

Id be hesitant to use any VM dependant language in serverless... I mean I love elixir and built my startup on it but I'd never consider trying to run it as a lambda function for the same reason. You're fighting against the grain.


> Cold starts for Java serverless (lambda) are worse than scripting languages

I've run plenty of Java applications in Lambda and they are pretty fast (like done in a few minutes fast). I've yet to try SnapStart which can make those workloads even faster.


I have successfully written entirely serverless APIs in Go. It’s not a great fit for everyone, but was for our use-case. Cold-starts became a non-issue compared to Java.


1. Yeah but serverless is completely unnecessary. JVM rewards you for long running processes. CRaC etc are there if you really care about that though.

2. If your Java code is using 5-10x more memory for the same task you are doing it wrong. Java objects do have higher overhead vs Go structs but not an order of magnitude. You could also be tuning the heap wrong, Java will use all the memory you give it and it won't be quick to give it back unless you tell it that it should.


> serverless is completely unnecessary

I don't care for lambda either, but you can't just hand-wave away a huge portion of the current web. Devs use lambda, tens of thousands of them in fact. Java has an expensive startup and it affects them.

> you are doing it wrong

Perhaps, but I've seen it over-and-over again. Maybe you're extra talented, but regardless all us regular people seem to keep producing systems that are much more expensive to run with Java.


I didn't handwave it away. I alluded to there being existing solutions CRaC, AoT, GraalVM, etc. There are ways to entirely eliminate cold-start as a concern if it's important to you

My point was you don't ever -need- serverless. You might like it for whatever reason but it's completely unnecessary when long-lived processes can get the job done and have so many benefits. JIT of course but also connection pools, memory-local caches etc that all much much more important than "being on serverless" which is mostly a net-negative once you look at the picture more wholistically.

I also think it's wrong to go "hey I want to use serverless, what works well with serverless?" insted of going "what is the best tool to solve my problem? Ok now what is the best environment for that to run?".


I feel that you've ignored all the reasons why folks feel that Go is more reliable and faster than Java.

Fighting with the JVM - even in modern versions - is an absolute pain. The practical reality of using _any_ JVM language is wasted memory footprint, classpath issues, weird dependency graphs because a mega-apache-project was used to solve a simple problem, etc. Never mind getting basic things like RPC clients over TLS (fighting with openssl and keystores? in 2023? really?) working.

> my real point was Java is easily faster and more reliable than Go and it seems pretty insane to reach the opposite conclusion

Citation needed. Disagree in practical observation.


As if there aren't plenty of blogs about fighting Go runtime, some of them giving up, and doing rewrites in C++ and Rust.

https://discord.com/blog/why-discord-is-switching-from-go-to...


Oh I am well aware of Java's warts and you hit a few of them but they are clearly -not- performance or reliability.

Yes there are lots of things that suck about Java and the JVM but you can't in good faith argue that it's slow and unreliable.


Once it hits full stride, sure. While not a Java dev, I work with plenty of Java enterprise systems (looking at you, ElasticSearch, and probably big chunks of AWS).

One appreciates the engineering durability of it all.

I do refer to the healthy startup time for the cluster as the "Java pause".

Perhaps that's a cheap shot, blaming the language, given that we're getting rich logging and a predictable approach that makes things boring in a good way, but there you have it.


Yeah the JVM definitely makes tradeoffs that adversely affect startup time, things like autowiring DI, etc all contribute to this - it's not just the runtime. It can be slightly annoying so periodically effort is invested to make it fast again, see recent Spring Boot startup speeds which are pretty damn quick now but can be made super fast with static wiring. (all without needing to resort to CRaC or AoT)

I was really getting at the fact that you can't reasonably call something unreliable or slow when it's probably powering some of your most loved (and performant) distributed systems that your applications rely on - doubly so if you are running on AWS or GCP. If it was either unreliable or slow, let alone both it wouldn't be fit for purpose.


Having worked on one of the largest golang code bases on the planet, I agree completely. I would always think to myself how much simpler and more reliable the programs I saw would have been in Java. But hype is hype I suppose, not to mention so many unsubstantiated claims.


Could you please tell a bit more about your project, I'm very curious.


It was a monorepo, with many hundreds of programs in it. I worked on a handful of them, but I was able to see what other people were writing.


> these days with @NotNull and powerful editors like IDEA stopping you from doing dumb things

I'm so sick of these half-arsed "features" that somehow get adopted into Java code bases.

Stop what you're doing and go write a unit test for @NotNull (or @NonNull). Watch the null value happily bypass those "checks".

Or, use (or write) a notNull() method (I happen to use commons-lang3) and watch it actually work.


I agree - but in a comparison of Java vs Go - in Go there's no support for checking nulls at all, which is surely worse than Java's situation.

I mean you can literally assign nil to a "func" type, and then call that func and it'll panic at runtime. Neither the compiler nor the JetBrains IDE will warn you about that, and there are no @Nonnull type annotations you can add (even if they're not ideal as you rightly point out).

That literally happened to me last week, just a stupid coding mistake, but took quite a while to find. In Java IntelliJ would have probably warned me about that, and certainly if I'd added @Nonnull annotations.


Here's my last week story. I was trying to debug an NPE, so I added the `notNull(` line in the follwing:

  @PUT
  @Path("/{rest}/path")
  @LogBody
  public Answer controllerMethod(
    @PathParam("param1") UUID param1,
    @ApiParam(required = true, value = "body") @NotNull @Valid Body1 body1) {
        notNull(body1, "Annotations are a joke. This null value made it through reqired=true, NotNull, and Valid");
        return service.serviceMethod(param1, body1);
  }
And sure enough that line was hit:

  2023-09-08T07:34:34,511 ${env:K8S_POD_IP}  WARN  org.eclipse.jetty.server.HttpChannel - /api/v3/service/rest/path
    javax.servlet.ServletException: javax.servlet.ServletException: org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException: Annotations are a joke. This null value made it through reqired=true, NotNull, and Valid
      at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:162) ~[jetty-server-9.4.44.v20210927.jar:9.4.44.v20210927]
      at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:179) ~[jetty-server-9.4.44.v20210927.jar:9.4.44.v20210927]
      at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[jetty-server-9.4.44.v20210927.jar:9.4.44.v20210927]
I just don't know what is to be done at this point. I don't know how the median Java programmer doesn't walk away after getting burned by this one.


I get what you mean, it's certainly confusing.

There are various different @NotNull so I'm not sure which you're using, some (but not all) of them are more compile-time contract type things. So if you called that method with null then you'd get an error from a code analysis tools. But that @PUT method is called by the framework at runtime based on an incoming REST request, there's no line in your code which calls the method with null, therefore nowhere for the code analysis tool to see the error and report it.

So yeah, all really confusing, and doesn't always do what you want. Nevertheless, I feel that at least there is a chance to use them and they do sometimes find bugs, which is better than Go's situation of having no way to specify that a method shouldn't be called with null. So if you do call such methods with nil in Go, even in a way that could never work, and which would theoretically be detectable at compile time, you just always get a runtime crash.


Perhaps another factor the article was referring to is that Go compiles ahead of time to static binaries. Java is typically JIT compiled which means extra overhead and unpredictability at runtime as code warms up.


> the only knock you can put on Java for reliability is null-safety

FWIW, nullity control has been added to the Valhalla project, so it might be fixed going forward.

https://youtu.be/Ma0NtbG0mHY?feature=shared&t=1076


The usual Java bashing from Go folks, meanwhile Google keeps mostly using Java, Kotlin and C++, with only a couple of key projects using Go, like Kubernetes or Google downloader.


I was a witness to a decision on whether to migrate an old Java project to Go. A proof of concept (a Go rewrite of a core part of the engine) convincingly showed that the Go version would be somewhat more performant, would have vastly better startup time, and would have a smaller and simpler codebase, since the Java version's caches and latency-hiding complexity would not be needed.

The decision made was to stick with Java.

Why? Because rewriting the long feature tail of the Java version in Go and ensuring bug-for-bug compatibility with the Java version would have taken multiple engineer-years. During the rewrite, from the perspective of the project's users, development would have stalled. It made more business sense to instead use those engineer-years to implement some new features that users were demanding. And after all, while the Java version's performance wasn't amazing, it was acceptable.


Golden question being what would a rewrite in Java achieve.


Java has been awesome for a long time so it’s boring to write blog articles about it and it doesn’t signal any hipness on your resume or GitHub profile. The problem with Java is really…almost all the Java code that has ever been written.


I work in cloud and every single one of our new projects is in go


Also work in cloud and we only do .NET, Java, and node, coupled with C++ when needed.

Anecdotes.


That's surprising to me, I don't think .NET or node are approved languages at Google. Are you part of some acquisition?


I work in cloud, as in, cloud native development, targeting AWS and Azure based infrastructure.


Ah got it. I was talking about Google Cloud


This particular thread is about golang use in google. So your comment doesn't appear to apply.


It is called Go, and whatever.


I’ve heard three main arguments in favor of using Go. First, that it has a standard library that is world class for building a worldwide ads serving network. If your use case is that or something that’s technically similar, then it’s great. Second, Go has extremely limited facilities for abstraction. Frankly, I dislike that about it, but the argument is that forcing programmers to use a quite limited set of abstractions makes code more readable. I have my doubts, but the argument isn’t prima facie absurd. Third, it produces statically linked binaries that you can copy and run on any machine of the same architecture.


> that it has a standard library that is world class for building a worldwide ads serving network

What does the golang standard lib have for that use case that Java doesn't have, or do better?

> but the argument is that forcing programmers to use a quite limited set of abstractions makes code more readable

There's a good balance. Sure you can probably argue that Scala opens the door for many different ways to write a program. But golang took the extreme opposite approach, resulting in very verbose code that is difficult to decipher. Java has a very solid middle ground here.


I agree that Java definitely strikes a middle ground. It has enough features you can write code in the ways you want (generics, first class functions) but not so many you can create unintelligible messes (implicits).

I generally tend to think of Java is "truly general purpose" because it has enough speed/scalability to implement a database while being generally easy enough for beginners to learn and providing enough scope and structure for building big line of business applications (where only really C# competes). Outside of embedded (excluding smart cards) and the browser mono-language you would be hard pressed to find a field that you can't use JVM to effectively solve a problem.

Java I would still call verbose, it's more verbosity than I tolerated when I was greener but I have come to appreciate a certain amount of ceremony isn't necessarily bad - if it helps to efficiently communicate the intent of the programmer.

I guess what I am trying to say is Java is easy to read, easier even than Go IMO because Go's verbosity is in the wrong places, i.e error handling, loop iteration ceremony, struct construction, etc. while Java's is more inherent to class/application structure which does more to communicate intent.

One thing I did like about Go though from a readability perspective though was their take on visibility. By eliminating the public/private/internal visibility modifiers as seen in JVM code it becomes simple at a glance no matter where you are in the codebase if a method is part of a public API or not just based on it's capitalisation.


> Java I would still call verbose, it's more verbosity than I tolerated when I was greener but I have come to appreciate a certain amount of ceremony isn't necessarily bad - if it helps to efficiently communicate the intent of the programmer.

In my experience the trick with Java is to use a purpose built editor like Eclipse or IntelliJ. Once you've achieved competence with an appropriate tool the syntax kind of fades from your attention and you focus on the important parts. Kind of like how experienced Lispers using an appropriate editing mode don't really pay much attention to the parentheses.


100% agree.

It was tough coming from a VIM only workflow to IntelliJ but I am really glad I toughed out the transition.

The power is in how all the tooling comes together but it requires a certain investment to get there.


Yeah those are all good reasons to consider Go.

I think the static binary argument is a bit flat though.

With Java I don't even need to compile for multiple architectures, I can copy a fat-JAR onto any machine with a JVM and it will execute. i.e an artifact with exactly the same hash and no worries about Mac OS X DNS resolver weirdness or CGO nonsense.


but now you have the nonsense of dealing with jvm versions and choosing the right one


That is fairly overblown, especially post Java 9 (2017).

Generally speaking you just target a minimum version if you want to not distribute the JVM itself but these days most Java software is backend software, most of which is containerized, packaging the runtime with the code itself.


But bad news if you actually need a decent interface to C libraries.


> Non-blocking code with synchronous coding style? Virtual Threads are much much better than goroutines.

That's going to need some justification. I work with Java and Go. I haven't worked with Virtual Threads yet but my understanding is Go's approach to goroutines and Java's approach to Virtual Threads are pretty much equivalent. (Channels, however, are quite different.) Let me know if I've missed something.


The runtime is similar, both are continuation based under the hood etc.

What sets VirtualThread apart is that all the support you get from the Java Stdlib. i.e ExecutorService and friends and now ThreadGroup with the improvements in Java 21. Not to mention the structured concurrency features that are planned to complement them. Another key difference is how much easier they interact with interrupts for cancelation without having to resort to context, channel and select hacks.

Compare this to Golang where this is very little tools for managing groups of goroutines. You have the sync package, specifically WaitGroup which get you some of the way there but it's still massively behind the equivalent JVM stdlib support for real concurrency. JVM has equivalents to everything in the sync package but in addition to that it for instance the collections library which contains ConcurrentHashMap, which naturally works perfectly with VirtualThreads vs Golang which map is not goroutine safe and you have to go outside the stdlib to get concurrent safe structures.

So yeah, if you are working in Java already you should checkout VirtualThread for your i/o intensive needs, especially if you were using Go for those tasks before.


Embedded devices?


Older versions of ARM had hardware support for translating and executing Java bytecode, see Jazelle.


- Webcrap - use Go. The arguments for Go for that use case is that 1) Google provides the libraries for most web back-end things you'll need, and since Google uses those libraries internally, even the obscure cases have been exercised, and 2) Goroutines are both low-cost and can block, so you don't have to face Rust async/thread combo hell.

- Hard problems that have concurrency, performance issues, or have to be highly reliable such as a database - use Rust.


I've used Go and Rust for a number of highly scaled services that you've definitely interacted with if you do something online.

In my experience Go does fine with a lot of concurrency and the GC can make some dirty lockfree tricks a lot easier. It also has a much more mature contribution story: Go test, go bench etc. work the same and proff endpoints in production are a godsend. We never really had a time we couldn't have used Go.

Rust has a slight performance advantage with some sharp edges around designing for the borrow checker, as well as much less fleshed out core set of libraries. The C interop story is better and async does work but can get messy.

Overall I think the tradeoffs are in ease of understanding, experience of team and tooling vs. the extra bit of performance, and can go either way.


> Webcrap

Highly recommend sqlc.dev, goa.design, gokit.io, gql-gen, bind, and all the other code-generation libraries in Go.

Don't write all that code by hand. Figure out your domain objects, queries, revolvers, etc.., generate the code, then deploy it.


Why Go for web and not Typescript with nodejs/deno. The ecosystem is also huge and widely used. The type system is miles ahead of Go and is closer to rust. The async await is single threaded too.


Why use an ecosystem that needs 2-3 layers of build tooling, none of which is designed to work together when you can use any of the sane stacks instead? Not to mention the hell that is Jest, Eslint and trying to make those play with aforementioned 2-3 layers of crap. Then you also have to put up all the downsides of purely single threaded concurrent programming instead of Go M:N model which is much less prone to problems like event loop exhaustion.

Go for all it's faults has one build system/tool and spits out machine code, hell it does that probably 10x faster than just tsc can typecheck.

Personally I don't like either but Go > Typescript seems like a no-brainer unless you are hell bent on the isomorphic code thing and all the extra work that entails. i.e. making sure someone doesn't reference window in an isomorphic lib or node APIs in the opposite scenario, etc.


Go is significantly more performant and can natively use multiple CPU cores without needing work-arounds with things like service workers. I've had to convert a few node.js services to Go to overcome raw speed issues.

Rust is even better, but not everyone wants the added complexity on their projects.

(also, I haven't worked with bun yet)


I question this myself as bun.js is approaching golang speeds.


I highly doubt it's doing type checking though so you aren't going to be eliminating tsc from the picture even if you are using bun.js unless you want to just cross your fingers and hope for the best.


My ide does a pretty good job saying something is wrong without using tsc.


The features vs versions graph is more than a little nonsensical, and its conclusions even more so.

> They should be stable and move slowly so that most of the time of your develoeprs is not spent fighting with their tools.

I can't speak to Go's tooling base, but Rust's is head and shoulders above any other ecosystem that I've had to work with. This is definitely more a point in Rust's favor than against.


Go's tooling is much better in one key aspect, compile times. Rust's compile times and feedback loop are terrible and it is not a community priority (ie. they want to make it faster, but only incrementally and not the orders of magnitude improvement it needs). Go's could be better but at least it is a priority.


Rust's compile times are worse than Go but are still way better than people make it to be.

Here are some examples:

---

Rust Analyzer:

Clean build: 31.02s

Incremental build: 3.07s (Added a `println!` in a level-2 dependency in the dependency graph)

SLOC: 306,467

SLOC of dependencies: ~879,304 (After removing `win*` packages which make up for another 1.3M)

---

Zola:

Clean build: 24.58s

Incremental build: 1.34s (Added a `println!` in a level-2 dependency in the dependency graph)

SLOC: 17,233

SLOC of dependencies: ~2,087,781 (After removing `win*` packages which make up for another 1.3M)

Obviously, not all source code gets compiled due to conditional compilation but it makes for a good approximate if you only take into account 2/3 of it.

---

For comparison with Zig by building ZLS:

Clean build: 20.13s

Incremental build: 10.27s (I believe this builds the ZLS package again from scratch so not really incremental)

SLOC: 45,806

SLOC of dependencies: I don't know how to get this.

---

This was on a Ryzen 5600x


At the hobby level in Rust I am constantly in awe of how good the Rust tooling is.


Go’s is ok. Not as good though.


Can you provide an example of where rust has better tooling than Go?


Offhand, I like rustfmt a lot more than gofmt because it handles long lines rather than only changing things within a given line; in my opinion, any time I need to manually format something myself, that's a failure of the formatting tool. I also find rustdoc to be much more flexible than Go's documentation functionality (which I forget the name of, but I assume it's something like `go doc`). At least the last time I used it Go required me to prefix any doc comment for a given function, type, etc. to start with the name of the item I was documenting; not only is this redundant, but it also means that any typo I make will cause the comment to be omitted completely, whereas Rust only requires a third slash for doc comments (i.e. `///` rather than just `//`). It's a minor thing, but small quality of life things add up across an entire ecosystem.


Prefixing doc comments with the ident name is a convention that isn't enforced in any way. You must have been using a 3rd party linter.


So any comment that happens to be right before a public type, function, etc. is exported into documentation without any special syntax needed? Honestly, in my opinion that's even worse, given that part of the whole point of tools like this is to generate public-facing documentation for websites; I want doc comments to be visibly different than regular comments, but it sounds like the only thing that would determine whether a comment is exported is the surrounding context.


You're just making problems up now ...


I don't agree with much of this - especially if the alternative is Go. I'm a semi-fan of Go but there are really very few situations I'd pick it over Rust.

> Rust is the 14th most used language

I think the author is a bit confused about "most loved" - that means that people who already use it want to keep using it. 14th most used language is great for such a young and not beginner friendly language. It's only 1 place behind Go and that is 3 years older.

Additionally Rust is mainly replacing C/C++ codebases which are generally much older and slower moving than other languages.

> Now imagine being the developer tasked with updating the dependencies of a service that is 31 versions behind... > During the same period, there was 8 Go releases, 7 Node.js releases (but only 2 LTS) and 3 Python releases.

This is obvious nonsense. The stability of a language is not measured by the number of releases. Come on, did this guy really write a successful book about Rust? Is this satire?

> Rust is actually still in the beta phase, with some important features such as async Traits still missing, which brings more churn to the ecosystem.

Really? Is C++ "still in beta" because it doesn't have async?

> The standard library is anemic

Sure that is an issue in C++ where using third party libraries is a huge pain. Doesn't really matter so much when you can just `cargo add regex`.

> async is hard

This is the only vaguely valid point. But on the other hand 90% of the time the solution is simple: don't use async.

Very disappointing article. I was expecting an actual good comparison of the pros and cons. Go does have some notable advantages over Rust - compile time, ease of cross compilation, simplicity, goroutines, built in fuzzing support, arguably better dependency management. Why not talk about them?


> almost as easy to use as Python

At risk of starting a flame war, I don't find Python easy to use at all so I have to question anything the author says at this point.

I was first introduced to Python 25 years ago and stuck with QuickBasic, C and assembly. I recently tried to do some opencv stuff with Python and the dynamic typing made even the simplest things exhausting. Then there's the virtual environment and dependencies situation which is easy to make a mess of if you don't know about it upfront.

I found a C# library to do the same and was way more productive and finished the task at hand quickly.


Did you try using a python IDE like Pycharm? Also python has type hints now and many libraries expose them.


Which do you like better? Programming languages are not things to be judged based on some random criteria, but by how well they fit how your mind works and let you express the ideas you want to express. Different languages hit these points for different people.

Best advice you'll get is to try both (and more) and use the language you like best and that best aligns with the type of work you enjoy.


One point that a lot of those "actually, just use Go" articles fail to recognize is that there is a sizable amount of developers who simply dislike programming in Go.

Despite its impressive compilation speed and bundled tooling and whatnot, some (myself included) find it tedious and uninteresting to program in Go, with tons of repetition and verboseness. Some people are more utilitarian and don't mind, but not all think the same.


Yep. For me Concurrency and CSP are why I learned Go and why I still use it today. I love thinking concurrently about problems and how data and control flow through those systems. It was a natural fit for me in those aspects and the other language warts don't get in the way enough to matter.


Go and Rust do not compete at all in the same domain. A long time ago, Rust did not have the focus it as now and even included a GC

But now, asking Go vs. Rust does not make sense at all.

If you want a mediocre speed application with fast development, use Go

If you want good memory footpeint with mediocre development use rust


> If you want a mediocre speed application with fast development, use Go

I don't know if you can describe much of Kubernetes like that.


Why not both? I spend most of my time in Go, but learning other languages is always on my radar, most recently OCaml. It's just fun and helps keep me spry, if that makes sense.


What’s your thoughts on Ocaml? I’ve been curious Facebooks heavy use of it


They do?? Sauce?



I remember reading years ago that the hack compiler was built in ocaml. compilers and such are often built using languages with nice ADTs afaik.


The Rust compiler was bootstrapped from OCaml as well!


Like any time this is asked the real answer is "it depends" while the answer given in the post as in all posts like it is "you should use my favourite instead of your favourite". There's no depth here and nothing that hasn't been said before, don't waste your time.

I know HN isn't a fan of "middlebrow dismissal" but go on, read it and tell me it says anything beyond "I like red better than blue"


> When Rust makes sense

It’s missing a subheading for “anytime you do not want a garbage collector” which is true for almost anything real-time / graphical etc


I think the main point it's missing: what is the context? In the absence of context, any answer is both correct and incorrect, like Schrödinger's cat :D


The context is wanting to write an article that makes the front page of Hacker News.


haha .. well, it definitely makes sense


So Ive been tugging on this myself. I came up with one heuristic for myself.

If you need to write microservices (especially for control planes where there good concurrency and distributed system patterns needed) - I find Go be a fine combination of performance (GC hit will be there over Rust), ease of deployment, programming model (CSP) - at a slight expense on verbosity (say compared to python and you also get used to this with your patterns).

If you need high perf/low latency/near C (embedded systems level) performance - with a type system assisted memory management - then Rust.

I have found Go's stdlib to be pretty thorough (and the ecosystem to be awesome too). Yes you will always find that set of X things hard to find that others dont care about. But horses for courses.

I have invested in learning both (but I also find learning languages a joy). But if you absolutely only have time for one consider your use case and pick appropriately. Yes you can do Rust for services too but given all this dual asyn model discussion still ongoing and a lot of real world services/control planes in Go there are already good Go patterns you can leverage right away at a much lower learning curve.


This feels like the beginning of a long blog post I'd like to read.

Go feels natural to me, Rust feels like an ugly looking, needlessly complicated language.

Go has decay too. Many packages are abandoned or not properly taken care of. Generics did their own to slow the language down. But even if it's not the fastest language, it's fast and robust enough to get things done. And that's what counts for me.


> Rust was Stack Overflow's most loved language for 7 years in a row ... and yet, was ranked as the 14th.

Go is ranked 13th. Seems weird to use language popularity as a criticism when you're only choosing between the 13th and 14th place options.

Besides, in 2023 their "All Respondents" usage is almost identical, with Rust showing stronger year-over-year growth than Go.


Use the tool for the job. I use Rust where it makes sense - georust is very useful to me. If I need simple web services I use Typescript. Image processing? Python and numpy. Low latency event handling over web sockets? Java and Lmax disruptor. Modern tooling and IDEs are great, using four or five languages is not that hard.


I’m curious, given the current state of Rust, what can be done to help with these issues?

Most of them seem related to the way the community organizes itself, and what they value at any given moment.

What would a non-anemic STD look like? Could the STD be broken into smaller pieces while still being a standard library?

Async has been a point of major frustration for me from the onset. Some people love it some hate it. Is there a good way to appease both sides? What can be done to make the libraries more generic between the two? Having to reimplement everything for async is a nightmare.

As for feature bloat in general. I agree, Rust still feels sorta like beta software, but it’s also matured a lot. I’m not sire there’s an optimal rate of feature addition, though I do wish existing feature polish was a higher priority over new stuff. Funny, I was just thinking about this last night while I was stuck trying to fall asleep.


>> What would a non-anemic STD look like?

More like the standard libraries found in C++, Ada, Go, or Python.

Why can't Rust do something like C++ does with Boost?

If everyone is using a given crate (for example, serde) why not "adopt" it into the standard library? Give the maintainer a plaque that looks cool and a small fee for initial adoption and a recurring stipend for continued maintenance.

The crate becomes official, gets guaranteed maintenance and there is less need to reinvent the wheel or worry that a good crate will go unmaintained or have issues.


Note that boost is also not the C++ standard library.

A few people have tried to make boost-like meta-packages in Rust over the years, but in practice, people don’t use them, and they die out.

Also, like, serde's main maintainer is also a member of the libs team, so it being moved into the standard library meaning more maintenance doesn't really make sense to me.


>> Note that boost is also not the C++ standard library.

I know, but many components that are now in the C++ standard library were previously in Boost or were heavily influenced by / inspired by Boost:

https://stackoverflow.com/questions/59912393/boost-libraries...

Similar events also happened in Java 8 with the Joda time library:

https://www.joda.org/joda-time/

>> serde's main maintainer is also a member of the libs team, so it being moved into the standard library meaning more maintenance doesn't really make sense to me.

I did not know that.

I was just using serde as an example of a widely-used crate that feels essential enough to be included in the Rust standard library.

At what point does a third-party crate become so useful that it might be considered for inclusion in the Rust standard library?

Is there a process for adding crates to the Rust standard library?

If so, how do such crates get nominated and approved?


The process is roughly the same as the boost one: the rust project maintains a number of packages outside the standard library, such as regex. Projects may graduate from the community to being owned by the project. And then, if the team decides that it's a good decision, a package owned by the project can move into the standard library.

It happens pretty rarely because there is not much advantage to doing so, but the path does exist.


This is usually a very simple decision. Do you need the performance of Rust? If not, use Go (or Java or F# or C# or whatever GC language you prefer)


> Do you need the performance of Rust? If not, use Go

Or, if GC is not an option - like operating systems, embedded software, web engines and game engines. That said, why not just use Rust for everything if you know it?


You can use any language you like for your pet project with a single contributor, but there are more considerations if you want to have/move a team to that language in business environment.


Agreed. That's certainly a good criterion.


Finally, a pragmatist on this Rust vs Go maddness. Thank you


As someone who doesn't know either language, would love HN's opinion on this video that was recommended to me by another HN user on a Rust thread a few days ago:

https://www.youtube.com/watch?v=p-tb1ZfkwgQ

The general gist of the video is the creator prefer Rust for functional programming and programs without much state and Go for everything else. As someone who's coming from a React background I don't see why if Rust is brilliant for functional programming why it can't also be good for programs with state if the right design decisions are taken to handle it - can you not just use a redux style store with actions and reducers?


I have experience in Rust, but not in Go. The video was more informative than I expected - a lot of comparative insights into the type systems. Ocaml sounds interesting. And while personally prefer Rust for everything, I agree that Go might be the better choice if the developers have to learn it from scratch or have to develop the application quickly. Rust takes a lot of effort to reach the level where you can appreciate its advantages. Once in a while, you can see someone cursing Rust because they were forced by the management to use Rust to develop an application under a tight deadline.

Rust, on the other hand, guarantees memory safety, pushes you to design better programs and cuts down on debugging time a lot. Rust is the better choice when correctness and performance matters. And if you are comfortable with Rust, it's good for almost any task.

> The general gist of the video is the creator prefer Rust for functional programming and programs without much state and Go for everything else.

Rust has no problems with handling states, as you guessed. They can't be global states (like in Go?). You have to group the state variables logically and pass them around. An additional constraint is that the data structures should be in a tree form. The ownership rules make it hard to have circular and mutual references in data structures (it's still possible with things like Rc and unsafe blocks).

Whether all this is an advantage or disadvantage really depends upon your preference. For example, I usually have a single large config object in my Python programs, whereas Rust forces me to split it up into manageable pieces. Frankly, I prefer the Rust style for multiple reasons: 1. Global states and circular references are an easy recipe for disastrous bugs. 2. Splitting up large state variables into smaller ones make it easier to reason about the purpose of each code section - it encourages more modular, refactorable and reusable code. (Splitting up data feels magical. All the problems seem to suddenly disappear when you reach a certain level of segregation) I haven't yet worked on a program that can't be written in Rust.


Very informative reply, thank you


One argument/scenario for the use of Rust I'm surprised not to see more often is interop with Python.

A ton of code, ML/AI etc goes through Python sooner or later. For example, as I understand it, PyTorch and Tensorflow, for instance, are written in C++, but primarily to be used in Python.

There are very few languages I know of that have compelling interop with Python. C, C++, Rust... Nim? All other major languages have something but as far as I can tell, it is usually some kind of hack/rpc kind of thing.

Clearly doesn't apply to every project, but one key reason why I'm learning Rust is precisely that I care about Python interior, and don't much love C++.


I'm a little tired of this endless discussion ... it always pops up with programming languages, they are tools, use whatever is more fit for what you're doing, move fast, break things, learn


Some languages are better than others. I don't see what's wrong with debating it. Do you also get annoyed at people debating which football team is the best or the best cars?


This is about how to determine what is more fit for what you are doing.


I'm going to restate here again: Go is static compiling friendly, you just ship a single executable and you're done, can't believe how easy is it to upgrade down the road.

rust, java, etc are much more complex.


Ok, so I'm no expert on Rust or Go or whatever, but I've noticed that many posts and comments seem to rip on Go, and that Go is bad, Rust is better, language X is better than Go, etc etc.

My question is why all the hate on Go? And if Go is so bad as these posts claim, why compare everything against it?

I'm not saying Rust isn't good or anything like that, but why the never ending hit pieces on Go? Lets just evaluate Rust or any language on its own merits.

I agree comparisons can be useful but its getting out of hand with these never ending Rust vs. Go pieces.


You should Typescript. Performance comparable to Go. A more flexible typing system than both. Easier to learn than both. A worse package system, but that can be mitigated with discipline. What Typescript currently lacks the most is affordances for embedded or performance intensive work as it's single threaded, but when performance matters use NAPI to use Rust in your Typescript, but the trajectory of performance of V8 and Webkit is such that I wouldn't be surprised if Typescript is within the same order of magnitude for performance as Rust soon enough.

:P


Typescript uses an order of magnitude memory that Go. It also doesn’t support concurrency. With on Go pod you can have a web server that automatically uses multiple cores. You’ll get better performance in the real world as a result. You’ll pay less for it too.


Yes, Javascript is single threaded. This has its benefits and drawbacks. In many applications using the Cluster API is enough, but as you said you'll never be able to do super performance stuff with Javascript, but you can use NAPI and call Rust if you'd like.

Memory usage is pretty good with Go, yes. I'm skeptical how much this matters in a real world application, though.


HN's memory usage obsession is basically a meme now. You'll see vastly more JS consternation here for RAM usage than praise for benefits like getting MVPs up stunningly fast, having a gigantic hiring pool, using one codebase to deploy on every major platform, etc. (These critics are often ironically the same folks who endorse avoiding premature optimization.)

And hey, memory usage can be crucial! But the community's distorted emphasis on it is almost comical, when compared to reality. I think it's an understandable perspective, given some devs' proximity to bare metal. But man I wish it wasn't such an omnipresent refrain here. :/


It’s great for bootstrapping. A $5 droplet at Digital Ocean is more affordable than $25 per month. The same is true if you take advantage of lambdas. Quick boot up. Able to do more CPU work per unit of time. All because it’s fast and low memory.

Also the dependency world isn’t as messed up at it is in Typescript. I’ve been spending the better part of my time fixing dependabot issues. Some package I don’t know about is causing me to have to upgrade everything. Crazy stuff.


Is it really meme? There is often opinion that developer and business friendly process is more important than user experience and energy resources.

I do not think that there is single narrative.


I love TypeScript for back-end work. Node.js is astonishingly fast, thanks to V8. TS is concise, has a wonderful/expressive type system, can share code/types with the front-end, and has libraries for damn near everything.

It's the easy choice for new projects. And yeah, if/when it's time to optimize later, and the raw performance of V8 ain't enough, you can reach for threads, WASM, or Rust. 10/10 experience.


> As far as I know, today, Rust is the only programming language (other than C) able to create efficient WebAssembly (wasm) libraries

Zig is also a good option for that, but the language is still in development.


Regarding Zig, note that the author writes "starting a new project in a memory unsafe language in 2023 is foolish as demonstrated by the endless flow of vulnerabilities."


Yes but that's a silly argument for most software, which will never see adversarial contact.


Maybe once Zig supports WASIX


No, let's actually have a standard with some thoughtful design instead of just bunging a bunch of ancient POSIXisms along into another platform. Also, as far as I can tell, it's being pushed exclusively by Wasmer which looks to be a bit shady as a company.


Wasmer attempted to do this in the Ziglang repo barely 4 days ago:

https://github.com/ziglang/zig/issues/17115



I’m pretty sure that’s what the parent is referring to :)


wasm is enough to do fancy things in the browser, games for example, with Rust or Zig. WASIX is not necessary for this.


As someone with very little expertise in this, and from the very little time that I can spare for experimental webdev, from a webdev framework perspective, Rust is where Go was 7-8 years back. There are some Rust frameworks available which look promising (rocket), but golang has much more. On the flipside, There is nothing wrong with golang (or at least it has less wrong going for it as compared to the js frameworks), but Rust is appealing because it IS the next big thing.


I think you need to qualify the aspects, in which you think Rust is 7-8 years back. I rather have the impression, that the designers of the Go language had a too simplistic view of what Go should offer and then it took them 12 years to get something as common as generics. Rust has many language features and of course had generics waaay before Go. In general it seems the Rust ecosystem does sometimes have things later, but therefore better or correct when it arrives at a solution. In terms of language design Go is the one that seems way behind.


Shocking but true: you could program things in Go before generics.


Now a pile of legacy code needs to be burned to the ground and replaced (it sounds like a lot of Kubernetes was generated to work around it). In the Java ecosystem we’re fortunate that this is long since finished.


This author has a habit (in this posts and prior posts) of the content of the paragraphs not connecting the dots for the claims made in the headings.

> Rust is (over)hyped

Whether it is or isn't, the content of the following paragraph does not justify the heading. It cites the StackOverflow surveys that says people like Rust and then cites adoption, but doesn't connect these points. It's possible for something to be hyped but not adopted much if it's new-ish.

The heading itself is also unclear. Is the author saying "overhyped" or "hyped"? Pick one.

Additionally, the author doesn't connect this heading to the overall article. They should explain why something being (over)hyped means you should not pick it.

> Rust projects decay

The rest of the paragraph talks about the Rust release cycle but doesn't connect the dots to why this causes Rust projects to decay.

Any Rust code written after the v1.0 release is guaranteed to compile forever. If you upgrade your compiler by 30 versions your code will still compile. A new release of Rust doesn't mean you have to drop everything you're doing and upgrade. If you want to upgrade once per year, you can do that.

The same points were raised on the author's previous article ("Programming Languages are Platforms") which was another article that raises points in the headings that are not described further in the paragraphs.

> Rust is still beta (despite the 1.0)

This paragraph says "related to the point above" but it's not related. In this section they say that Rust is missing features (it is) and in the previous section they were implying that it's bad that Rust is adding features.

This heading is also obviously intentionally inflammatory. If Rust not having async Traits makes it "beta", would the author have considered Go to be "beta" for 10+ years when it didn't have generics. Generics as a feature are *much* more integrated with fundamental parts of the language and cause ecosystem churn & split. See also Java and C#.

(For the record, I wouldn't consider either of those situations to be "beta" and think the suggestion is preposterous)

> The standard library is anemic

Meh, "anemic" is a pretty inflammatory word and I wouldn't go that far. It's intentionally bare bones to avoid bad design decisions that can't be removed in the future and so far that's been pretty successful.

Does the Go standard library even have map/filter yet?

It seems like this author's idea of a non-anemic standard library is that it has a builtin HTTP server. They also suggest in other articles that Rust needs to have a builtin templating language as well. They suggest that not having this builtin leads to bugs, as if a standard library can't have bugs as well? The link between these points is tenuous at best.

> async is hard

These paragraphs are pretty good.

___

All in all, it's a provacatively written article that's sure to generate discussion, and especially discussion unrelated to the article itself, but unfortunately there's little to no logical flow in the points that it's trying to make.


Isn't it obvious, just use what everyone use (golang at the moment)? Is your role as a software engineer NOT a job/creating values for other people, but to "influence technology" or some sort of activism? I know that there are software engineers like that, but I just don't think most people are. Many seem to be confused why they do what they do apparently.


> I think that a modular and rich standard library such as Go's or Node.js's offers way higher productivity to developers, consistency to the ecosystem and reduced costs for businesses.

Is the Go standard library really considered rich? Coming from languages like python or ruby I found it pretty lacking. Admittedly I haven't used Go in 3 years.


All of these things are a spectrum. For network services especially, Go's standard library is generally considered pretty comprehensive, yes. In comparison to Rust specifically, like the context of the post, I don't think anyone could really argue a different way, though if you're comparing to something else, or for a different kind of task, it's possible that you may have a different opinion, sure.


I felt like it had a lot to do things web related but was pretty lacking on primitives for algorithms and data structures out of the box.


Honestly? Though I am forced to write go at work, I take Rust in a heartbeat(and it is a constant moaning from my end to ditch go and use Rust all the way almost every day). First thing to keep in mind is that Rust today is nothing like the Rust of 2015, even 2020. Way too many things are wrong with go: The packaging is one thing which I absolutely hate. I can't find words to express how much I hate the import "github.com/whatever" and that is a clear indication of the fact that packaging is an afterthought, which historically was a problem the language designers chose to ignore and kick the bucket down the road, hoping the community figures it out. Another clear indication of this is everything around the environmental variable hell: GOROOT, GOPATH and all that. Error handling is another horrible thing: ok, err := whatever() is absolutely wretched, even more so when you have to write the function definitions. Even when all linters are happy with the code, I can't look at it without thinking "this looks as beautiful and idiomatic as a roadkill". While coroutines(I hate the name goroutines) are cheap, they are not a universal solution to all problems and with that in mind, having a compiled language with no actual threading is ridiculous: threads are a great thing to have(I know this goes much deeper but let's not turn this into a novel). While both languages don't have inheritance, at least with Rust you have some tools to help you generalize basic things: macros. The statement that golang has all you need in it's standard library is a complete joke. While the ecosystem has grown immensely over the years, I feel like it's reaching the point where it's comparable to the npm hellhole.

With Rust you get a perfectly thought out packaging. You also get the best of both worlds - runtimes and threads. By design you are pushed hard to properly handle errors. Some of my large Rust projects take forever to compile, I'll give you that, but there is a good reason for it. The compiler is actually helpful and in a lot of the cases it tells you exactly what you need to fix when you mess up. And don't even get me started on performance. I have the exact same microservice implemented in both go and rust. And while I did not opt for the most performant rust web framework (poem), it's not even a race, it's a straight up massacre: when I benchmark the two with wrk, the difference in performance is literally 11 times - same database, same openapi specification, same logic. While the Rust standard library lacks a lot of things, even some basic functionalities, cargo takes care of it for you with 0 effort: cargo new whatever, echo 'rand = "0.8.4"' >> whatever/Cargo.toml and you are done.

Don't get me wrong, this is not a "bash-golang" comment. But I can't deny that when I put the two side by side, go looks like a toy language.


C looks like a toy language too, when compared to C++. And yet some of the best software in the world is written in it.

So yes, Go has its drawbacks. But it is easy to get things done with it.


C a toy language? C is arguably the most difficult languages to master from the (relatively) mainstream languages. Far more difficult than C++ imo. I've gone through a lot of C and C++ code over the years and, I'm fully standing behind Torvald's opinions of it. As far as get things done, you could say that about any language really - Python, Haskell, Julia, hell, even PHP and js get things done easily. The example I gave above - the Rust microservice is not more than 10-15% larger in terms of codebase compared to the go one. The gains in performance and code which is actually pleasant to read is well worth it.



Should I Rust or should I Go now?

Should I Rust or should I Go now?

If I Go there will be trouble!

If I Rust it will be double!

So you gotta let me know!

Should I Rust or should I Go?!

(I'll see myself out now...)


You should probably C that wherever you go there you are.


If you Go, there will be trouble. But if you Rust, it will be double.


My POV:

Rust for OS kernel programming, e.g https://github.com/dancrossnyc/rxv64

And go for practically anything outside that scope: web service, CLI tool, etc.


Luckily I have written up my heartache with Rust at https://news.ycombinator.com/item?id=30954078 so I don't need to do it again.


Glad I read this. No need to waste my time learning Rust.


Never touch Go and your life will be better.


GO


Go


Rust is not a good match for embedded Linux so long as binary sizes are so gigantic (same is true for a lot of C++). When your binary takes 100 MB of a few GB emmc, you have a problem.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: