Live data from Hacker News

Rust 1.45

blog.rust-lang.org

141–150 of 227 posts

Re: Rust 1.45

#141
post #137

This rather niche fixing of unsafe behaviour is excellent: https://blog.rust-lang.org/2020/07/16/Rust-1.45.0.html#fixin... I spent a few years as a scientific programmer and this is exactly the sort of thing that just bites you on the behind in C/C++/Fortran: the undefined behaviour can actually manifest as noise in your output, or just really hard to track down, intermittent problems. A big win to get rid of it.

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?

Re: Rust 1.45

#142
post #68

Earlier quoted context omitted.

Way worse than that, even. UB poisons every state of the program that eventually results in UB. For example, the optimizer is well within its rights to remove as dead code any branch that, if taken, would provably lead to UB at some arbitrary future point of execution.

That could literally produce no output program?

> That could literally produce no output program?

Way worse than even that (you might be noticing a theme here...). Once the optimizer has removed as dead code any branch that, if taken, would provably lead to UB at some arbitrary future point of execution, it can conclude that the other branch is now the only possible execution, and call it unconditionally, even if that leads to removing all your files (the classic example is https://kristerw.blogspot.com/2017/09/why-undefined-behavior...).

Re: Rust 1.45

#143
post #56

Earlier quoted context omitted.

When working with audio as an example, saturation is much less obnoxious than wraparound. You can potentially destroy speakers and your hearing that way.

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 nukes on everything in sight, somewhat uncharacteristic of him.

Fans liked this so much that Firaxis maintained the same behaviour in later games.

Re: Rust 1.45

#144

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

> 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

#145
post #137

Earlier 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?

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 systems, while the semantics of saturation are just subtle corruption that is almost useless to "use" for anything valuable (and are inconsistent, unless they are also doing it for integers? like if I cast a floating point to a 64-bit number and then to an 8-bit number do I get a truncated result instead of a saturated one?... I hope not, even though I reject saturation as a reasonable semantic). But if it is defined legal and guaranteed behavior, what should a tool do in this scenario? It can't say "you have a bug here" as maybe you wanted that behavior.

Re: Rust 1.45

#146
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?

Re: Rust 1.45

#148

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

Re: Rust 1.45

#149

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?

Writing macros (in any language) is a way of creating an abstraction. Creating abstractions is a way of automating the job of programming, making it ideally more efficient and less error prone. This is why people usually prefer java to basic. Marcos are a way of creating abstractions that are particular suited to be "concreted" by the compiler, making them a ideal match for programming languages that seek to be "close to the metal" like C, C++ and rust.

C Macros are lacking because they are very primitive, e.g. they have not type system. They are also hardly turing complete. Its extremely hard to write a meaningful algorithm in them. IMHO the real macros of the C++ language are the templates and constexpr, althou they are limited in other ways. E.g. its hard to extend the syntax using them or do certain things like making the calling function return. They grow ever more powerful, with their own type system (concepts) and things like std::embed and static refection so they finally feel like a real language, alsbei a clumsy, pure functional language that feels alien a C++ programmer without exposure to haskell.

Rust macros are actually meant to feel like Rust, not some ad-hoc bolted on language.

Re: Rust 1.45

#150

The post says The new API to cast in an unsafe manner is: let x: f32 = 1.0; let y: u8 = unsafe { x.to_int_unchecked() }; But as always, you should only use this method as a last resort. Just like with array access, the compiler can often optimize the checks away, making the safe and unsafe versions equivalent when the compiler can prove it. I believe for array access you can elide the bounds checking with an assert l…

It should be `assert!(len(arr) >= 255)` (greater instead of less than), right?

actually >, not >=
Post reply on HN