Live data from Hacker News

Migrating from Go to Rust

corrode.dev

111–120 of 544 posts

Re: Migrating from Go to Rust

#111

Earlier quoted context omitted.

A &(dyn Error + 'static) should be fine for that; you don't need any allocated/variable sized data in a memory allocation failure.

stacktraces? might also be useful to know whether or not the latest allocand was a jumbo sized allocand that caused the failure?

Do you really want that data passed back down to the caller of the allocation? From the description of the failure state you'd want to log that data instead: what's the caller of the allocation going to do if you tell it it failed with a crazy size? It already knows the size, it's the one who asked for it.

Re: Migrating from Go to Rust

#112
Read migrating from one hype to another, developers never learn or change, do they??

It feels like yesterday when every single project was moving to Go just because it was the new hype, that was until Rust was born.

We are already seeing projects dumping migration to Rust because the grass is not always greener on the other side.

We will be seeing this again, "Migrating from Rust to XYZ"

Re: Migrating from Go to Rust

#113

Earlier quoted context omitted.

I guess you might have to if you need to use a library someone's written that doesn't implement the standard. Writing primarily applications, I couldn't tell you what error handling frameworks my dependencies are using: I literally don't know, and haven't needed to know in order to display, fail, or succeed. EDIT to add: I use anyhow for this, so I should also add "add context to an error when I fall" to the list of…

What's the standard? I'm not being snarky; I'm going down the thought process of how this would work in practice. I am on team Io Error [on std rust]", somewhat arbitrarily. If I call a lib that is on Team Anyhow, or Team Custom Error Enum, I will have to do some (Straightfoward, but a little clumsy) conversions if I want ? to work. This is complicated by being able to impl From for ErrorType2 only in one direction i…

By standard I meant an error type that implements std::error::Error.

EDIT: Which I assume all my dependencies have done, given that anyhow is able to consume all of them.

I specifically called out writing applications as my use case: my only objection to tptacek's note is the somewhat universal "in practice". The burden for designing errors for a library that others will use is higher, but that's far from the default/universal experience.

Many more people are going to consume libraries & not produce any of their own, and I think my experience is representative there.

Re: Migrating from Go to Rust

#114

Earlier quoted context omitted.

They all convert seamlessly, and the enums make the branches explicit. Don't even need to check the documentation to find which errors supposedly exists like in Go with its errors.Is, errors.As, wrapping and what not. An easy rule before you make a knowledge based choice is Thiserror for libraries, helping you create the standard library error types and Anyhow for applications, easy strings you bubble up. Or just go…

I’ve repeatedly tried using Rust and the error handling has tripped me up every time and has been ~90% of the reason for moving a project back to another language. I’m sure I’m just holding it wrong, but what I run into usually goes something like this (mind you, I have read the Rust book): * Someone tells me to use enums for errors, in a comment like yours * I try writing the enums by hand, implementing the error tr…

How come you get macro expansion errors? Or is it because you write incorrect syntax in the enum error definitions?

The example on the docs page is quite clear:

https://docs.rs/thiserror/latest/thiserror/#example

Including all kinds of errors: Strings, tagged unions and automatically converting from std::io::Error with added context.

That one page document is the entire documentation for the thiserror crate.

Re: Migrating from Go to Rust

#115
post #87

Earlier quoted context omitted.

I was a big fan of go for a while. Though now that I have programmed more swift and rust recently, having a compiler that doesn’t protect against null pointer deferences or provide concurrency safety guarantees feels a little prehistoric. Though go certainly did a much better job than rust on the standard library front.

Standard library is something you have to maintain for all eternity, with identical API. It had been argued that some concurrency primitives like channels would have been better outside of std (for rust, to be clear). Once dependency management is solved, a small std is beneficial.

> you have to maintain for all eternity, with identical API

People always tout this as a huge reason for not wanting a too big std in Rust (or "too useful" either), but IMHO that's just talking about reaching theoretical optimals, while leaving the community for years without good guidance via providing a opinionated practical and pragmatic way of doing things. Which I find to be a very unhelpful stance for a tool such as a programming language.

If a design of some std package didn't pass the test of time, and a new iteration would be beneficial, the language can leave its original API version right there, and evolve with a v2, with an improved and better thought out API after learning from the mistakes of v1.

Prime example: "hey we found that math/rand had some flaws, so here is math/rand/v2". A practical solution, and zero dramas as a result of having rand be part of std.

Re: Migrating from Go to Rust

#116
post #87

Earlier quoted context omitted.

I was a big fan of go for a while. Though now that I have programmed more swift and rust recently, having a compiler that doesn’t protect against null pointer deferences or provide concurrency safety guarantees feels a little prehistoric. Though go certainly did a much better job than rust on the standard library front.

Standard library is something you have to maintain for all eternity, with identical API. It had been argued that some concurrency primitives like channels would have been better outside of std (for rust, to be clear). Once dependency management is solved, a small std is beneficial.

I use go because of the large and useful stdlib. I rarely have to reach for an external library, and even then I only consider libraries that are very popular. If a library isn’t available, I’ll just write my own, using the stdlib. I recently used the awesome crypto library to implement an envelope encryption system, I didn’t need anything outside of the stdlib or Google’s x library (x is effectively the experimental stdlib).

Having too much external code, like npm or rust crates, seems like a nightmare for me.

Re: Migrating from Go to Rust

#117
post #51
post #6

I could see migrating from C or C++ or Python to Rust, for various reasons, but for web back-end work Go is a good match. I write almost entirely in Rust, but the last time I had to do something web server side in Rust, I now wish I'd used Go. The OP points out the wordyness of Go's error syntax. That's a good point. Rust started with the same problem, and added the "?" syntax, which just does a return with an error…

For me the main advantage of Go over Rust is compilation speed. Then compared with Go Rust still rely on many C and C++ libraries making it problematic to cross-compile or generate reproducible builds or static binaries. The minus side of Go is too simplistic GC. When latency spikes hit, there are little options to address them besides painful rewrite.

What kind of apps are you writing where GC spikes matter?

Re: Migrating from Go to Rust

#118
post #6

I could see migrating from C or C++ or Python to Rust, for various reasons, but for web back-end work Go is a good match. I write almost entirely in Rust, but the last time I had to do something web server side in Rust, I now wish I'd used Go. The OP points out the wordyness of Go's error syntax. That's a good point. Rust started with the same problem, and added the "?" syntax, which just does a return with an error…

For backend web dev, there are advantages. I really like Axum's use of typing: pub async fn dataset_stats_handler( Path(dataset_id): Path , Query(verbose): Query , ) -> impl IntoResponse { ... } With a route like: .route("/datasets/{dataset_id}/stats", get(dataset_stats_handler)) …the "dataset_id" path variable is parsed straight into the dataset_id arg, and a query string "verbose" is parsed into a boolean. Super co…

go is slightly more verbose (surprise) but you can achieve the same thing using struct binding in gin:

    type DatasetStatsQuery struct {
        Verbose bool `form:"verbose"`
    }
    
    func DatasetStatsHandler(c *gin.Context) {
        datasetID := c.Param("dataset_id")
        var query DatasetStatsQuery
        if err := c.ShouldBindQuery(&query); err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
        // query.Verbose == bool
    }}
This is actually a great example - what happens in that Rust version when the input parsing fails? Go makes it explicit.

Re: Migrating from Go to Rust

#119

Earlier quoted context omitted.

Sure, but when we're talking single-digit seconds it feels not that significant regardless?

My point is that it isn't necessarily that fast. It is relative to the amount of changes and where they were made. For a fair comparison you would also have to present the worst case incremental build time which approaches the full build time (this goes for Go too), which per your own example is nearly a minute for rust.

> For a fair comparison you would also have to present the worst case incremental build time which approaches the full build time (this goes for Go too)

The worst case that would approach a non-incremental build time would be if you were editing a leaf crate. But in almost all cases the leaf crates are 3rd-party dependencies that you would never edit directly.

A real-world worst case is probably more like ~10-20% of an non-incremental builds.

Re: Migrating from Go to Rust

#120
post #3

I liked Rust before running a benchmark, but the gap between how effectively most LLMs write in Rust vs Go was still surprisingly large to me (especially in agentic harnesses where they can fix the initial environment issues). I've become a pretty big Rust evangelist after seeing that. We've had a lot of success writing batch processing tools in Rust to be called by our existing codebase, but haven't attempted a full…

The weakness of Rust WRT LLMs is compilation times. LLMs code faster and hence spend relatively more time waiting for compilation than humans do, so on reasonably sized projects (e.g. 100k+ lines) Rust's ~10x slower compilation starts showing up as a bottleneck. If you're writing some critical infrastructure it makes sense to pay that cost, but if you're writing some internal service that's not publicly exposed to th…

[dead]
Post reply on HN