As someone who hasn't used Rust, I am curious about why Rust has macros. I use C++ at work, which admittedly isn't the language I use most, and macros are used quite a bit in the code base. I find they just make the code harder to read, reason about, debug, and sometimes even write. I don't see them really living up to their claimed value. Is there something different about Rust's macros that make them better?
There is almost no intersection between the kind of things that can be done with the C++ macro system and the kind of things that can be done with the Rust macro system. They are not related. You can see them as another feature that is not available from C++.
Rust 1.45
151–160 of 227 posts
Re: Rust 1.45
#152Earlier quoted context omitted.
`as` is not considered idiomatic in Rust code,. `.into()` for infallible cases and `.try_into()` for fallible cases are preferred in almost all cases (in the case of floats there's still discussion around the correct behavior of `.try_into()` for edge cases). > So I think this is again an example of rust making a decision that hurts program correctness. Could you expand on other examples?
It might not be "idiomatic", but it isn't "unsafe", and so it is now providing a guaranteed behavior that... is it a bug? I certainly think saturation should always be considered a bug... like that's even worse to me than truncation as the semantics of truncation are at least interesting and related to mathematical basis of von neumann computing and sometimes extremely useful as a way to interact with memory-oriented…
Re: Rust 1.45
#153Earlier quoted context omitted.
`as` is not considered idiomatic in Rust code,. `.into()` for infallible cases and `.try_into()` for fallible cases are preferred in almost all cases (in the case of floats there's still discussion around the correct behavior of `.try_into()` for edge cases). > So I think this is again an example of rust making a decision that hurts program correctness. Could you expand on other examples?
It might not be "idiomatic", but it isn't "unsafe", and so it is now providing a guaranteed behavior that... is it a bug? I certainly think saturation should always be considered a bug... like that's even worse to me than truncation as the semantics of truncation are at least interesting and related to mathematical basis of von neumann computing and sometimes extremely useful as a way to interact with memory-oriented…
[1]: https://doc.rust-lang.org/nomicon/what-unsafe-does.html
[2]: https://nora.codes/post/what-is-rusts-unsafe/
[3]: https://play.rust-lang.org/?version=nightly&mode=debug&editi...
[4]: https://rust-lang.github.io/rust-clippy/master/#cast_lossles...
[5]: https://rust-lang.github.io/rust-clippy/master/#cast_possibl...
[6]: https://rust-lang.github.io/rust-clippy/master/#checked_conv...
[7]: https://rust-lang.github.io/rust-clippy/master/#char_lit_as_...
[8]: https://rust-lang.github.io/rust-clippy/master/#cast_sign_lo...
[9]: https://rust-lang.github.io/rust-clippy/master/#cast_precisi...
[10]: https://rust-lang.github.io/rust-clippy/master/#cast_possibl...
Re: Rust 1.45
#154Earlier quoted context omitted.
> I'm not sure I understand this. Does it not produce a run time error? Why not? It’s not supposed to. Type casting with ‘as’ is supposed to be lightweight and always succeed; there is no room in the type system to return an error. In case lossless casting is not possible, some value still has to be returned. Until now, this was outright UB — meaning the compiler is not even obligated to keep it consistent from one b…
Seems a pity they didn't add a built-in at the same time that's a bit more nuanced. It could maybe return an enum with Success(value), Underflow, Overflow and NaN. That way it's up to the coder to decide whether they want a saturating cast or to check the result explicitly.
Re: Rust 1.45
#155Earlier quoted context omitted.
Wraparound is also the bug that turns Ghandi into a huge dictator in Civilization, and killed a couple of people in cancer treatment devices.
For those not in the know, computer controlled Civs would be assigned behaviour attributes based on historical personality. Each attribute would be 1-10, stored in an 8 bit integer. These attributes change in response to events in the game. When a civilization would reach the modern era, it's aggression attribute would be reduced by 2. Gandhi's aggression was reduced from 1 to 255 (underflow). He would rain down nuke…
Re: Rust 1.45
#156Earlier quoted context omitted.
`as` is not considered idiomatic in Rust code,. `.into()` for infallible cases and `.try_into()` for fallible cases are preferred in almost all cases (in the case of floats there's still discussion around the correct behavior of `.try_into()` for edge cases). > So I think this is again an example of rust making a decision that hurts program correctness. Could you expand on other examples?
It might not be "idiomatic", but it isn't "unsafe", and so it is now providing a guaranteed behavior that... is it a bug? I certainly think saturation should always be considered a bug... like that's even worse to me than truncation as the semantics of truncation are at least interesting and related to mathematical basis of von neumann computing and sometimes extremely useful as a way to interact with memory-oriented…
Rust has a linter called Clippy which absolutely does call out things like that. It can do so because there are other mechanisms in the language which provide the same functionality without ambiguity. I believe casting with `as` is linted against by Clippy.
Re: Rust 1.45
#157Earlier quoted context omitted.
Right, but given that panicing was already allowable behavior, why was the new behavior chosen to be one likely to introduce subtle bugs? It seems much better to loudly proclaim the existence of an erroneous precondition, which is consistent with how things like array indexing behave. I guess I’ll have to go dig up the RFC discussion on this one; it should make for interesting reading.
I thing you are right about that, I'd prefer panicking too. Also, reading the RFC will surely clear up the motivation. Without knowing this case, I'd wager a guess: it's about performance. Panicking introduces a branch and side-effects which, again, affects negstively optimization potential and performance. The saturating cast affects performance too, but less. If some old code has a lot of number crunching containin…
Re: Rust 1.45
#158Earlier quoted context omitted.
That's not how versions work
>= 1.0 in semantic versioning universally means that it should be "stable enough"
Re: Rust 1.45
#159Earlier quoted context omitted.
It would be nice if there were both a saturating-as and a overflow-is-a-bug-as, the later of which is also saturating but in debug builds get instrumentation to panic if it ever actually saturates. The overflow-is-a-bug-saturating as would be the default, and there would be a separate sat_as for "I know this saturates, it isn't a bug.". ::sigh:: Rust went through this same debate for integers, initially rejecting the…
`as` is not considered idiomatic in Rust code,. `.into()` for infallible cases and `.try_into()` for fallible cases are preferred in almost all cases (in the case of floats there's still discussion around the correct behavior of `.try_into()` for edge cases). > So I think this is again an example of rust making a decision that hurts program correctness. Could you expand on other examples?
Yes it is. It's used all the time. There's a reason as_conversions defaults to Allow in clippy.
Of course, there are lots of situations where `as` is the wrong tool for the job, but I think it's a bit of a stretch to call `as` "not idiomatic". It's perfectly idiomatic in lots of situations.
Whether or not it should be idiomatic is a separate question.
Re: Rust 1.45
#160Earlier quoted context omitted.
I'm not sure I understand this. Does it not produce a run time error? Why not? This looks very dangerous, because it essentially does the "nearest to right" thing. Say, you cast 256 to a u8, it's then saturated to 255. That's almost right, and a result might be wrong only by 0.5%. Much harder to detect than if it is set to 0.
> Why not? For better or worse, Rust 1.0 released with the philosophy that the `as` operator is for "fast and loose" conversions where accuracy is not prioritized; e.g. casting a u32 to a u8 would always risk silently truncating in the event the value was too large to represent. Over the years the language has added a lot of standard library support for bypassing the `as` operator entirely, and I think the prevailing…