Giter VIP home page Giter VIP logo

Comments (25)

CraftSpider avatar CraftSpider commented on August 25, 2024 7

Rust backward-compatibility does in fact have fairly good documentation out there, though it's not trivial to find. This kind of situation is exactly why it's important to have policies - relying on the meaning of a thing being 'obvious' opens yourself up to different interpretations, as well as semantic drift.

Another note is simply - in its most strict form, a 'Breaking Change' is anything that turns working code into not-working code, for some abstract code that relies on the current behavior. This definition is why Rust distinguishes 'major' and 'minor' changes - just about any change could break some code, so we specify certain things that, while technically 'breaking', we have declared within our rights to change anyways. This change specifically is 'major' because it hits all of the following (not all major changes are all of the following, and this list isn't all the reasons a change could be major):

  • It changes user-visible behavior
  • It changes behavior that has been guaranteed by documentation
  • It would render many currently correct programs potentially incorrect, not just a tiny number of them

To quote RFC 1105, the API Evolution RFC, "But in some sense it is even more pernicious to make a change that allows downstream code to continue compiling, but causes its runtime behavior to break."

RFCs describing Rust's policy:
https://rust-lang.github.io/rfcs/1105-api-evolution.html
https://rust-lang.github.io/rfcs/1122-language-semver.html

Documentation of what constitutes a 'major' vs 'minor' change for external crates:
https://doc.rust-lang.org/cargo/reference/semver.html

from rfcs.

Diggsey avatar Diggsey commented on August 25, 2024 5

I find them very un-Rust-like in the sense that they are implicit and you can never be sure exactly how your program works.
I never said arithmetic should change its return type, that's what the checked operations do. I said that it simply shouldn't panic and instead return 0.

Returning zero would be very un-rustlike. Rust prioritizes the following:

Correct program > Panicking program > Incorrect program > Undefined Behaviour

ie. a panicking program is better than an incorrect program, so making arithmetic operations incorrectly return 0 would make things worse.

from rfcs.

kennytm avatar kennytm commented on August 25, 2024 3

@coolCucumber-cat

Ok, I wasn't aware of not allowing changes. Where does it say that?

https://github.com/rust-lang/rfcs/blob/master/text/2052-epochs.md#negative-examples-what-edition-opt-ins-cant-do

I said that it simply shouldn't panic and instead return 0.

For integers x / 0 returning any concrete number is simply wrong (integers don't have NaN or ±Infinity)

If you need to ensure divide-by-zero never happens make your denominator use the NonZero type.

from rfcs.

BurntSushi avatar BurntSushi commented on August 25, 2024 2

So to be clear, you're proposing that slice[i] be removed from Rust in the next edition? If so, this issue can be closed because it's a non-starter. It's never going to happen.

Editions aren't a license to do arbitrary breaking changes.

from rfcs.

ChayimFriedman2 avatar ChayimFriedman2 commented on August 25, 2024 2

Silent changes in behavior are exactly breaking changes.

from rfcs.

senekor avatar senekor commented on August 25, 2024 2

@coolCucumber-cat maybe this clippy lint serves your needs: arithmetic_side_effects.

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024 1

@BurntSushi

No, it should just return an Option or Result instead. If you want it to panic, you can unwrap.

If I did mean that, then the rest of my proposal can still go through.

And it's also not an arbitrary change.

from rfcs.

kennytm avatar kennytm commented on August 25, 2024 1

BTW you could force your binary to never able to panic by using https://docs.rs/no-panic/latest/no_panic/ which turns the panic call into a linker error.

from rfcs.

Diggsey avatar Diggsey commented on August 25, 2024 1

You can consider division by 0 being 0 because anything divided by 0 makes infinity, which overflows to make 0.

And in debug builds Rust panics on overflow, because it's an error. It would do so in release to if it weren't for the performance cost of checking it.

Can you give an example where 0 would be worse than panicking?

In any situation where you actually want a correct answer? If you end up dividing by zero it means something has gone wrong earlier in the program. It's better to panic than allow the program to continue and potientially do something completely unexpected.

from rfcs.

senekor avatar senekor commented on August 25, 2024 1

is there a lint just for side effects that also panic?

I don't know, but the site I linked to has a search feature for all available clippy lints.

I wouldn't consider a change like that to be breaking, what is a breaking change then? I can't find anything about it in the docs.

I'm not aware of a Rust-specific documentation about backwards compatibility. To me it seems so obvious it doesn't have to be documented. If the thing doesn't do anymore what its documentation said it does, that's a breaking change. I would consider a silent breaking change like that to be much worse than a change in the API which the compiler will at least give me good messages about. A broken build is annoying, broken production is a catastrophe.

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024

@kennytm What's wrong with my suggestion? Feedback is appreciated.

from rfcs.

kennytm avatar kennytm commented on August 25, 2024

@coolCucumber-cat Edition is only designed for change syntax, once a std library interface is stabilized it is there forever.

That is, since u64::div(u64) returns u64 in Edition 2015, it will always return u64, not Option<u64> nor Result<u64, DivError> in edition 2999 as long as it is still called "Rust 1.8554" not "Rust 2.something".

That is the "arbitrary breaking change" called out by BurntSushi above.

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024

@kennytm Ok, I wasn't aware of not allowing changes. Where does it say that?

I never said arithmetic should change its return type, that's what the checked operations do. I said that it simply shouldn't panic and instead return 0. I think you meant to say that indexing shouldn't its return value, not arithmetic.

And I said it wasn't arbitrary, not that it wasn't a breaking change. I even said that it would break things.

So currently, the only problem is indexing, which I can remove from this RFC.

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024

@kennytm @BurntSushi I removed indexing from this issue. Are there any other problems that need to be addressed?

Arithmetic not panicing is not a breaking change, but it would cause some programs to behave differently. That is allowed though, right?

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024

In my opinion, returning 0 isn't incorrect. NaN for floating points has similar behaviour, but isn't considered incorrect. Neither is an overflow. I just don't see how panicking is better than a silent failure or what could break by instead returning 0.

You can consider division by 0 being 0 because anything divided by 0 makes infinity, which overflows to make 0.

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024

Can you give an example where 0 would be worse than panicking?

from rfcs.

kennytm avatar kennytm commented on August 25, 2024

The only cases I know that x / 0 == 0 are

  1. The Pony language, which actually have 3 division operators (x / 0 == 0, x /? 0 == error, x /~ 0 == undefined behavior). However x / 0.0 == ±inf.
  2. Provers like Lean and Coq because they require the function to be total and divide-by-zero shouldn't happen in the domain the proof should be working on (they also sort-of defined 100 - 250 == 0 for unsigned numbers).

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024

I agree with what the Pony language has done: "So, in order to maintain a practical API and avoid undefined behaviour, normal division on integers in Pony is defined to be 0.".

When you divide by 0 with a floating point number, it produces NaN, which is not correct either. So if that's allowed then 0 can just be the equivalent of NaN but for ints.

In dev mode I think it should panic, as it does now, but in production I don't think it should because it doesn't even help you catch the error. Whoever is running your program will just get a random error that probably doesn't matter.

from rfcs.

kennytm avatar kennytm commented on August 25, 2024

When you divide by 0 with a floating point number, it produces NaN, which is not correct either.

No you get +Infinity if x > 0, -Infinity if x < 0 and NaN otherwise.

This is correct in the context of float as in conforming to IEEE 754.

So if that's allowed then 0 can just be the equivalent of NaN but for ints.

Except that NaN is not 0 (nor ±∞) in float


In any case redefining x / 0 to return 0 today is a breaking change of runtime behavior according to #1105 since the contract to panic is documented already.

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024

When did I say that NaN is 0? I said we can use 0 as the int equivalent of NaN. I forgot about infinity, I really meant anything that isn't a real number (NaN, ±Infinity).

I know that it is correct according to IEE754, but if it's correct to have an unexpected value that isn't technically correct like Infinity (which is not a real number), then surely 0 can be allowed when dividing by 0.

What's the definition of breaking change here? Because nothing breaks, just that the behaviour changes.

from rfcs.

mohe2015 avatar mohe2015 commented on August 25, 2024

When did I say that NaN is 0? I said we can use 0 as the int equivalent of NaN. I forgot about infinity, I really meant anything that isn't a real number (NaN, ±Infinity).

I know that it is correct according to IEE754, but if it's correct to have an unexpected value that isn't technically correct like Infinity (which is not a real number), then surely 0 can be allowed when dividing by 0.

What's the definition of breaking change here? Because nothing breaks, just that the behaviour changes.

The issue with that would be that 0 would then mean 0 or NaN or +-Infinity without being able to differentiate between them. For floating point numbers you can differentiate between them which is a major difference.

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024

@senekor is there a lint just for side effects that also panic? it's a helpful lint to avoid divisions by 0 but annoying for side effects that only overflow

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024

@ChayimFriedman2 There's clearly a misunderstanding here. I wouldn't consider a change like that to be breaking, what is a breaking change then? I can't find anything about it in the docs.

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024

@senekor So you mean anytime that a change would make the current documentation incorrect? Yeah sure I guess that seems reasonable.

from rfcs.

coolCucumber-cat avatar coolCucumber-cat commented on August 25, 2024

@CraftSpider Thanks, this would have been nice to know before. I wish it was easier to find though. I for sure agree it's a good idea to have policies, but it defeats the point of them to be hidden. Do you have any tips to make it easier to find things like this? Because I constantly cannot find things like this.

from rfcs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.