Migrating from Go to Rust
421–430 of 544 posts
Re: Migrating from Go to Rust
#422Earlier quoted context omitted.
I'm so perplexed by this, because Rust errors are what make the language so amazing. > Now I’m debugging macro expansion errors and spending approximately the same amount of time This never happens once you've learned the language a bit more. Anyhow and thiserror are a cinch. > I realize that this is pretty tedious, manual work, so someone points me to thiserr or similar Claude writes Rust so effectively. It can do a…
I think Claude may be what makes me use Rust successfully. Firstly it’s ability to deal with the tedium and secondly not needing to solicit help from people who tell me my problem is trivial while giving contradictory solutions :) > And the type system will mean that Claude emits better code on average. I’m curious if this is true. I believe that it emits better code than with a dynamically typed language, but as wit…
I'm so sorry for this btw.
The problems are trivial once you've used Rust for n hours, for some value n. It's just that these folks forgot the learning and headache they went through.
You're going to build that same recognition and familiarity using Claude over time. It'll seep in pretty quick, I'd imagine.
> I’m curious if this is true.
Being forced to emit an Option or Result and then having to actually use syntax to get at the goods forces the code to deal with errors the appropriate way, clearly, idiomatically, and typically in a good flow that is amenable to readability and easy refactoring. Other languages without Option, Result, and sum types baked into the language so fundamentally do not have this advantage.
I feel it every time I have to work in a TypeScript codebase, for instance. It's a strongly typed language, and can emulate sum types via discriminated unions. But that doesn't convey the same advantages because it doesn't enforce anything. It's far too lose to have the same advantages Rust has.
I think you'll feel the same way as you use the language more and more.
Re: Migrating from Go to Rust
#423Re: Migrating from Go to Rust
#424Earlier quoted context omitted.
If you spend an hour skimming the Rust Book it's not really that bad
It's not that bad, but when compared to C or Go, it's not something that I would like to type by hand. At least Java has IDEs which reduce the amount of verbosity you need to type. I know you get safety, but the verbosity and cargo is is a con in my opinion.
Re: Migrating from Go to Rust
#425I 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…
> Rust has three main error systems (io::Error, thiserror, and anyhow), which is a pain when you have to pass them upward through a chain of calls anyhow explicitly isn't designed for what you are trying to do here. It's designed to be the last link in the chain (and complementary to thiserror, not in competition). If you are using anyhow any deeper than your top-level binary crate, you are likely to be in for an unp…
Re: Migrating from Go to Rust
#426This is a weird document that is simultaneously trying to serve as a migration guide and an advocacy document for Rust. Ultimately, if you have to ask , the Rust vs. Go consideration boils down almost completely to "do you want a managed runtime or not". A generation of Rust programmers has convinced itself that "managed runtime" is bad, that not having one is an important feature. But that's obviously false: there a…
Us Node folks adapted typescript because we wanted static compiled types. I wish TS had more of a runtime. The only thing I'm jealous of with regards to python is how seamlessly you can do JSON schema enforcement on HTTP endpoints. The Zod hoops are a constant source of irritation that only exists because the TS team is dogmatic.
Yes, it is much easier in Python because type annotations are reflected at runtime.
Re: Migrating from Go to Rust
#427If verbosity is a main stickler, this is coming to golang 1.28 which will cut it down drastically: https://github.com/golang/go/issues/12854#issue-110104883
Re: Migrating from Go to Rust
#428Re: Migrating from Go to Rust
#429Earlier 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…
1. thiserror just does codegen of the "standard" enum things people do. if you find debugging thiserror difficult, just write out the enums manually. sure it's uglier, but (roughly) equivalent. so its preferable as synctatic sugar for enums, but doesn't have any technical benefits (in the same way that syntatic sugar never really does).
2. for boxed errors, you only get allocations on your error path. Hopefully this is a cold path so it shouldn't matter.
There is a general theme behind rust error handling though which it can be good to internalize. In particular, the more details of your errors you encode in the type system, the more powerful things are. Any error type could just be
pub struct MyError(String)
the issue is that this gives very little information to a caller on what to do with your error. If you have no callers (e.g. are making a binary) it's fine, and (roughly) what `anyhow` does.
That all being said, when designing errors a natural question to ask is "can my caller do anything meaningful with this error"? For example, in Rust stdlib, `Vec::push` can allocate. This allocation can fail, which panics. "Proper" error handling would use the fallible allocation API, and propagating an OOM error or whatever through results. For most applications, this is not an error that is worth investing that much time into guarding against, so using the (potentially panicing) `Vector::push` makes things easier.
You can take this same perspective in other settings as well, in particular separating out errors into
1. structured data, that a caller should be able to extract/process to handle the error, and 2. unstructured data, that is more used for logging, and you expect the caller to pass up the call stack without inspecting themself.
Handling both types of these errors with `thiserror` can be tedious for little benefit. I've found it useful to instead solely use `thiserror` for category 1, and category 2 does other things. This could be using `.expect(...)`. There are some crates that make this nicer (e.g. `error_stack`). But the point is that it can significantly clean things up if you only encode in your error enums failures that you expect someone to handle, rather than just e.g. log.
This does somewhat validate your point that the "right way" I've been experimenting with (and mentioned above) is not just "use this-error".
Also: a big issue with `thiserror` is the tedium of handling the large error enums (or giving up on using it "properly" and shoving together multiple error variants in some unstructured error type). that is somewhat better in the LLM era, as you can have the LLM handle the tedium.
Re: Migrating from Go to Rust
#430Earlier quoted context omitted.
The simplicity of Go is a feature…
I have to come to believe that Go is simple for the compiler , not necessarily for the programmer. `nil` is not simpler than references and Option . lack of enum is complicating my code. automatic type promotion is a hidden bug waiting to happen and preventing proper strong types, lack of `?` is making things verbose. struct tags look simple, until you realize they are hiding a ton of code and creating a ton of corne…
You're welcome to believe whatever you want but Go is pretty universally known as one of the simpler, easier to learn compiler languages in existence.