this post was submitted on 22 Dec 2023
28 points (91.2% liked)

Rust

5989 readers
34 users here now

Welcome to the Rust community! This is a place to discuss about the Rust programming language.

Wormhole

!performance@programming.dev

Credits

  • The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)

founded 1 year ago
MODERATORS
top 8 comments
sorted by: hot top controversial new old
[–] tatterdemalion@programming.dev 9 points 10 months ago* (last edited 10 months ago) (2 children)

"how to write sloppy rust code and squander most of the advantages of the language"

Only half serious. But I think really the only point that I agree with is taking the easy way out with the borrow checker. I mean, at least try to borrow when it's idiomatic, but if you get frustrated, clone (or move) instead.

Error handling when done well is not much harder than unwrapping everything, and you get many advantages. Learn to use thiserror for your library crates and anyhow for executables.

I also agree that you should avoid unsafe 99% of the time. If you think you need it, you probably don't.

[–] snaggen@programming.dev 5 points 10 months ago

I see this post as an advice to learn gradually, and to write sloppy but painless code initially. Then when you have the basics, you can add the more idiomatic and tricky parts.

[–] sugar_in_your_tea@sh.itjust.works 4 points 10 months ago

Exactly.

I have a strict no-unsafe policy. My projects don't need anything unsafe provides, so needing it means my structure is bad. Any unsafe blocks should only be in external crates and fully tested.

I'm also a big fan of getting function signatures right, even if they don't behave properly. For example, if I know a function could error, I'll go ahead and have it return a result even if every error path uses .expect(). That way my refactors are limited to just those functions, and probably not the functions that call it.

I'm a fan of writing relatively dirty code, as long as the dirty parts are obvious (e.g. have a comment explaining why certain shortcuts were made). But as much as possible, make the function signatures correct so refactors are easier.

[–] asdfasdfasdf@lemmy.world 3 points 10 months ago (1 children)

I agree with 99%, but not sure I see how async is a "fancy feature". When you're writing async code, async is boring and normal. I guess if you are writing programs that don't need to be concurrent it's fine to use sync variants of stuff.

[–] snaggen@programming.dev 4 points 10 months ago (1 children)

Well, when you write async code, you may suddenly find your self needing to implement AsynRead or something similar. Suddenly you have to use pin, and understand how async worksbunder the hood. So, while I agree that async is not something fancy, it will possibly throw you in some quite advanced territory. The part I'm not sure I agree with is skipping the error handling. But I see what the authors intention is, to keep hairy stuff out of the way while learning the basics.

[–] asdfasdfasdf@lemmy.world 0 points 10 months ago* (last edited 10 months ago) (1 children)

I've been writing async Rust professionally for 5 years and never needed to implement AsyncRead, or even Future directly. I've only used Pin for working with the async_stream macro. That stuff is very low level and probably would never be encountered by the vast majority of async users.

[–] snaggen@programming.dev 2 points 10 months ago

Well, you don't need it until you suddenly do. But I guess it might be very different for different users depending on your use case. I have found myself needing to go low level for async a few times, and I don't think I'm doing very strange things.

[–] sugar_in_your_tea@sh.itjust.works 2 points 10 months ago* (last edited 10 months ago)

I agree for the most part, with some exceptions

  • test the easy things - having a test suite that passes feels good, having some tests makes it easier to add more later, and testing utility code is usually pretty easy and important
  • make the important decisions correctly, the rest can be sloppy - e.g. decide early if you need async or multi-threading and get the signatures of your core code right, then take shortcuts on the rest
  • don't refactor unless it's blocking new features - it's easy to get sucked into "perfect code," so leave notes instead of doing the refactor

Basically, follow the 80/20 rule, get 80% of the important stuff right for 20% of the effort. Once everything is working, add more tests and refactor while getting feedback from users (if applicable).