Live data from Hacker News

Migrating from Go to Rust

corrode.dev

491–500 of 544 posts

Re: Migrating from Go to Rust

#491
post #425

Earlier quoted context omitted.

> 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…

also thiserror isn't incompatible with io::Error? all thiserror does is do code generation for "typical" enum errors. The errors it generates are normal rust code though, and the fact that they're generated by thiserror shouldn't really matter?

I don't get where the idea comes from that the popular error crates make error handling complicated in Rust. Because you're right, all thiserror is doing is giving you a shorter syntax for writing error enums. You could write the exact same things out by hand if you wanted to, and from the library user's side nothing would change.

As for anyhow, if a library ever exposes that, then that's just the author being lazy and not doing errors correctly. It's the equivalent of doing throw Exception("error!") in C#.

Re: Migrating from Go to Rust

#492
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…

> 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.

nit: Rust has three main Error implementations not systems. std::error::Error is a trait because it's left up to the user to provide project-specific error types, even if those types are anyhow::Errors. The system follows any implementation you use: ? syntax, .unwrap(), .expect(), handling, formatting, etc.

I've never had a problem using anyhow to pass errors up the call stack in any project I've used it in. What exactly is a pain?

Re: Migrating from Go to Rust

#493

I write purely Go at $dayjob, but I write purely Rust in my projects. I have a huge list of things that I have in Rust that I would like in Go, but I don't have a single thing I am missing from Go in Rust. I grow tired of golang "dumb it down" approach as I find it actually just shifts more and more work onto me. Is anyone in a different position? What does Go have that rust does not?

The simplicity of Go is a feature…

And the one I love the most.

Re: Migrating from Go to Rust

#494

Earlier quoted context omitted.

Interesting! Are Go backend building custom auth, admin, DB ORM/migrations/auto migrations, templates, email, dev server etc for each project? Or each person and org has their own toolkit they use?

>Are Go backend building custom auth, admin, DB ORM/migrations/auto migrations, templates, email, dev server etc for each project? lmao, basically, yes. except when you bring this up ppl think it's not a big deal / a means for self-expression. having to sort through which libraries you prefer to glue together is a kind of freedom, if you squint hard enough.

I get the "you're reinventing the wheel!" thing, but trying to fit a formula 1 car wheel to my horse-and-cart system really isn't working for me. I need a different wheel, so I'll just build my own. Luckily there's a ton of good libraries available that have all the tricky bits covered so it's relatively easy to build my own wheel.

Re: Migrating from Go to Rust

#495
post #396

> You literally cannot dereference an Option without acknowledging the None case. Whole categories of pager-duty incidents disappear. This is at the very least misleading, given that you can use unwrap. Regarding error handling: will a parser error in the config return an error that includes the name of the file that’s failed to parse? That’s the kind of useful context that I add to errors in Go.

Calling unwarp is acknowledgement

Re: Migrating from Go to Rust

#496
post #435

Earlier quoted context omitted.

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…

There's a number of things about rust that help compared to other statically typed languages. 1. the compiler gives very high quality error messages. It helps humans, and also helps LLMs 2. Rust reduces memory management to local reasoning (via the borrow checker). This means that it performs well even as context grows, because checks in one function/module are well-encapsulated to that function/module. 3. Rust can m…

> This is both good practice, and helps out LLMs quite a bit.

Don’t get me wrong, I like this aspect of Rust, but I can’t make heads or tails as to whether it helps or if they just have to iterate more to figure out how to make something work. LLMs already do pretty well with a comment “this value can’t be zero” in my experience, so I’m unsure how much value the static typing provides. Maybe it lets you get by with a lower quality model, but that model will likely just spend more tokens on iteration so I can’t discern an obvious win. (shrug) I hope I’m wrong though—if I can have super fast code with the ease of LLM generation then I’m happy.

> Rust reduces memory management to local reasoning (via the borrow checker). This means that it performs well even as context grows, because checks in one function/module are well-encapsulated to that function/module.

I don’t think this is true, right? Changing a single lifetime in a function signature can easily propagate across your entire program. Maybe I’m just a Rust noob, but any time I change a field from owned to borrowed or vice versa I have to propagate that change pretty broadly, which to my mind implies consuming a lot of the context window. Garbage collection (I know, ewww, shame on me, etc) allows for local reasoning in a much more meaningful way however morally impure it may be. :)

Re: Migrating from Go to Rust

#497
post #357

Earlier quoted context omitted.

Exactly. 95% of programmers are application programmers - they ship software used by regular users. I think it's insane to use a non-GC language for most of those cases. Manual memory management is mentally taxing and it's easy to make catastrophic mistakes. The marginal benefit from it is just not worth it unless you're making games or a trading system. 5% who write tools or other "infra" layer for the other 95% to…

> and it's easy to make catastrophic mistakes such as ... ?

Buffer overflows for one. I don't have numbers but many security vulnerabilities have some kind of memory safety problem underneath.

Re: Migrating from Go to Rust

#498

Earlier quoted context omitted.

Exactly. 95% of programmers are application programmers - they ship software used by regular users. I think it's insane to use a non-GC language for most of those cases. Manual memory management is mentally taxing and it's easy to make catastrophic mistakes. The marginal benefit from it is just not worth it unless you're making games or a trading system. 5% who write tools or other "infra" layer for the other 95% to…

Maybe I'm misunderstanding something but non-GC language doesn't mean you have to do memory management manually? I mean, for example, in Rust (or modern C++), it's basically automatic. There is no mental tax or catastrophic mistakes as far as I know.

That's true. GC and manual are the two ends of the spectrum with other options in between like Rust. By catastrophic mistakes I mean security vulnerabilities created by memory safety related mistakes.

Maybe it's just me but I cannot write a huge program in rust as easily as I can in Java or Python. I have to spend more effort bending my program to fit the language and it's semantics. I get safety and speed but it feel like I'm wearing a straitjacket for those gains paying in my time and productivity.

Sometimes that tradeoff makes sense, but if I'm writing a backend webserver or some other application why would I bother with all this effort. Just doesn't make sense to me.

Re: Migrating from Go to Rust

#499
post #244

Earlier quoted context omitted.

In my experience LLMs (I speak mainly of Claude Code & Cursor) write very poor quality Rust. They treat it like it's JavaScript, falling back to using String/&str needlessly instead of making new types. They do ugly `static Mutex Of course these are all surmountable with an experienced developer to regularly step in and unfuck the code, but forcing them into 'harder' territory where every problem is not solved by a .…

That is interesting. I make LLMs write C with the general hope that a simpler language they can manage well. That is not entirely true, though. They reason about C fluently indeed. The problem is, Claude pumps lots of bad C into the codebase if left unattended for 5 min. So, I need some clean-up passes afterwards to get to some acceptable quality level (both by LLMs and my own eyes). At which point, Claude sees the p…

> if left unattended for 5 min.

Is THAT how people use AI? I thought _I_ was vibe coding by telling it to write one function at a time and making sure I understand every line it outputs.

Re: Migrating from Go to Rust

#500
post #206

> It confuses easiness with simplicity A lot of libs/packages in Go's stdlib also has this problem. They like to package everything in a very tight interface (very obvious example includes crypto/* and http), without exposing implementation detail to the end user. Doing this of course has it's benefits, but if the feature provided by the stdlib slightly don't fit you needs, then you might have to write your own (pote…

I've come to hate hiding internals. Put them in a namespace which makes it clear there's no API stability guarantees, but make them available if needed. As you note it's just pain with no gain to properly hide them. Users can't readily work around bugs or extend functionality.

Sometimes hiding internals is reasonable, but it could cause inconvenient. Exposing everything could make it harder to do interface management etc.

It's really a system design problem rather than access control: if you separate functional modules in a reasonable way, then it can be better reused.

Post reply on HN