Live data from Hacker News

Rust Design Patterns as a Book

rust-unofficial.github.io

11–20 of 49 posts

Re: Rust Design Patterns as a Book

#11
post #6
post #5

A very low-effort way to learn good Rust patterns is to put #![warn(clippy::all)] at the top of your crate’s entrypoint. This enables Rust’s default linter. It’s a lot more friendly and focused on good design than you might expect, often suggesting more elegant alternatives. Plus, many of its suggestions can be applied automatically in an environment like VS Code + rust-analyzer plugin.

Thanks a lot for the suggestion, I can't believe I didn't know about this. However I just tried it and I can't get it to work. I added this to the top of https://github.com/etesync/etebase-rs/blob/master/src/lib.rs and then ran `cargo clippy` #![warn(clippy::all)] // Should fail https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp pub fn bool_test(x: f32, y: f32) -> bool { x == y } Any idea what's miss…

I’m not sure and can’t check at the moment; but maybe the functions not called so it’s being ignored?

Re: Rust Design Patterns as a Book

#12
post #6
post #5

A very low-effort way to learn good Rust patterns is to put #![warn(clippy::all)] at the top of your crate’s entrypoint. This enables Rust’s default linter. It’s a lot more friendly and focused on good design than you might expect, often suggesting more elegant alternatives. Plus, many of its suggestions can be applied automatically in an environment like VS Code + rust-analyzer plugin.

Thanks a lot for the suggestion, I can't believe I didn't know about this. However I just tried it and I can't get it to work. I added this to the top of https://github.com/etesync/etebase-rs/blob/master/src/lib.rs and then ran `cargo clippy` #![warn(clippy::all)] // Should fail https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp pub fn bool_test(x: f32, y: f32) -> bool { x == y } Any idea what's miss…

Does it work if you run `cargo clean` and then `cargo clippy` again? Clippy runs it's lints in an early pass of the compiler/checker. Many IDEs/editors will automatically `cargo check` under the hood to grab errors. Then when you run `cargo clippy`, that part of the compilation is already cached and so clippy doesn't give you any output :(

To my knowledge (it's been a while since I looked) fixing this behavior is blocked on cargo stabilizing something and has been for literal years.

That point of frustration aside, it's worth it...Clippy is an absolutely amazing piece of software. Both for pedagogy and normal development.

EDIT: Just dug up the issue. If you're on nightly you can use `cargo clippy -Z unstable-options` to avoid the clean/rebuild. Hopefully stuff gets stabilized soon. Here's the issue for reference: https://github.com/rust-lang/rust-clippy/issues/4612

Re: Rust Design Patterns as a Book

#13
post #6

Earlier quoted context omitted.

Thanks a lot for the suggestion, I can't believe I didn't know about this. However I just tried it and I can't get it to work. I added this to the top of https://github.com/etesync/etebase-rs/blob/master/src/lib.rs and then ran `cargo clippy` #![warn(clippy::all)] // Should fail https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp pub fn bool_test(x: f32, y: f32) -> bool { x == y } Any idea what's miss…

I’m not sure and can’t check at the moment; but maybe the functions not called so it’s being ignored?

It's public in my lib, so it's exported. Though I also tried calling it from my code, it still doesn't trigger a warning. :|

Re: Rust Design Patterns as a Book

#14
post #6

Earlier quoted context omitted.

Thanks a lot for the suggestion, I can't believe I didn't know about this. However I just tried it and I can't get it to work. I added this to the top of https://github.com/etesync/etebase-rs/blob/master/src/lib.rs and then ran `cargo clippy` #![warn(clippy::all)] // Should fail https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp pub fn bool_test(x: f32, y: f32) -> bool { x == y } Any idea what's miss…

Does it work if you run `cargo clean` and then `cargo clippy` again? Clippy runs it's lints in an early pass of the compiler/checker. Many IDEs/editors will automatically `cargo check` under the hood to grab errors. Then when you run `cargo clippy`, that part of the compilation is already cached and so clippy doesn't give you any output :( To my knowledge (it's been a while since I looked) fixing this behavior is blo…

That fixed it, thanks a lot!

Re: Rust Design Patterns as a Book

#15
post #6

Earlier quoted context omitted.

Thanks a lot for the suggestion, I can't believe I didn't know about this. However I just tried it and I can't get it to work. I added this to the top of https://github.com/etesync/etebase-rs/blob/master/src/lib.rs and then ran `cargo clippy` #![warn(clippy::all)] // Should fail https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp pub fn bool_test(x: f32, y: f32) -> bool { x == y } Any idea what's miss…

Comparing floats by equality is a dangerous pattern. It's easy for small precision errors to occur. You should instead check that they are close enough to each other, using an epsilon that you find appropriate, perhaps 1e-10. `(x - y).abs() < epsilon` should do the trick

It's in fact the dangerous pattern used to illustrate the linter under discussion here.

Re: Rust Design Patterns as a Book

#16
post #14

Earlier quoted context omitted.

Does it work if you run `cargo clean` and then `cargo clippy` again? Clippy runs it's lints in an early pass of the compiler/checker. Many IDEs/editors will automatically `cargo check` under the hood to grab errors. Then when you run `cargo clippy`, that part of the compilation is already cached and so clippy doesn't give you any output :( To my knowledge (it's been a while since I looked) fixing this behavior is blo…

That fixed it, thanks a lot!

Instead of `cargo clean`, `touch src/main.rs` or `touch src/lib.rs` (or actually touching any source file and thereby changing the `last modified` date to now) will have the same effect. That's what I've been using.

Re: Rust Design Patterns as a Book

#17
Is there anything that can be achieved by using the visitor pattern [0], that cannot be done by using pattern matching? I have only used the visitor pattern in languages that do not have pattern matching as a language feature (e.g. Java before it got a Scala-like `switch` construct [1]).

Edit: one limitation of pattern matching is, that all values need a common supertype (e.g. be variants of the same enum in Rust, if we see each variant as a type and the enum as the common supertype. There is an RFC [2] to make enum variants accessible as types), while the visitor pattern could be implemented for any set of independent types. On the other hand, you then cannot have a typed collection/container that contains values of these types, so you'd need some common trait like `Visitable` so you could accept an `Vec`.

[0]: https://rust-unofficial.github.io/patterns/patterns/visitor....

[1]: https://openjdk.java.net/jeps/8213076

[2]: https://github.com/rust-lang/rfcs/pull/2593

Re: Rust Design Patterns as a Book

#18
post #17

Is there anything that can be achieved by using the visitor pattern [0], that cannot be done by using pattern matching? I have only used the visitor pattern in languages that do not have pattern matching as a language feature (e.g. Java before it got a Scala-like `switch` construct [1]). Edit: one limitation of pattern matching is, that all values need a common supertype (e.g. be variants of the same enum in Rust, if…

The Visitor pattern is great if you want to process a data structure as "stream" without actually instantiating it, in the same way you can read a file line-by-line instead of loading it completely into memory.

For example, serde uses the visitor pattern to encode its intermediate representation. If it used pattern matching instead of the visitor pattern, it would have to instantiate its intermediate representation as an enum, which would add unnecessary overhead.

Re: Rust Design Patterns as a Book

#19
post #18
post #17

Is there anything that can be achieved by using the visitor pattern [0], that cannot be done by using pattern matching? I have only used the visitor pattern in languages that do not have pattern matching as a language feature (e.g. Java before it got a Scala-like `switch` construct [1]). Edit: one limitation of pattern matching is, that all values need a common supertype (e.g. be variants of the same enum in Rust, if…

The Visitor pattern is great if you want to process a data structure as "stream" without actually instantiating it, in the same way you can read a file line-by-line instead of loading it completely into memory. For example, serde uses the visitor pattern to encode its intermediate representation. If it used pattern matching instead of the visitor pattern, it would have to instantiate its intermediate representation a…

I guess you are talking about this `Visitor` trait [0]. I have only used serde in combination with the derive macros so please enlighten me, but each `visit_* ` function of the `Visitor` trait already takes a typed value (`bool`, integer types, ...) so these already have too be parsed (instantiated?) from the input string/bytes. Couldn't you have an `SerdeTypes` enum that implements `From` for each `visit_* ` type to remove some boilerplate and then use pattern matching? Could you elaborate where there would be overhead?

Don't get me wrong. I'm sure, the serde developers know better than me and have good reasons to implement it the way they did, but I'd like to understand the rational behind the decision.

Edit: formatting

[0]: https://github.com/serde-rs/serde/blob/master/serde/src/de/m...

Re: Rust Design Patterns as a Book

#20
Once you get past writing a language idiomatically, is a list of design patterns a good thing? It is an obvious negative for code readability because it reduces the number of people who can clearly understand your code from Rust users to Rust users who also memorize design patterns.

When are design patterns useful? And how are they useful?

Post reply on HN