News for hackers. Stuff that matters.
Re:Abstracting over ownership in Rust with higher-rank type ... by TakeBlaster16 on Sunday September 11, 2022 @10:51AM (#32800057)
There is a spectrum from obvious breaking changes (removing a method), to non-obvious ones (trait methods, glob imports), and beyond (https://xkcd.com/1172/)

Before adding methods to a trait, they test the change against all public Rust code known to exist, to verify no breakage. Very occasionally this causes them to put plans on hold or work with downstream library authors (see: the num-traits crate)

For the benefit of closed-source code, they also emit a warning before the change is made, so you have time to prepare or give feedback (https://doc.rust-lang.org/stable/nightly-rustc/rustc_lint/bu...)

It's a perfectly reasonable policy. I'm not sure what more they could do, unless you expect them to literally never change any traits ever again and ossify the stdlib into whatever state it was in 2015 when Rust 1.0 was released. If that's what you want, pin your compiler/library versions and you can have it!

Re:Abstracting over ownership in Rust with higher-rank type ... by umanwizard on Sunday September 11, 2022 @10:55AM (#32800114)
I’m fine with the current policy. What I would like them not to do is advertise “no breaking changes” as a major selling point of Rust, when that isn’t actually true.
Re:Abstracting over ownership in Rust with higher-rank type ... by jmillikin on Sunday September 11, 2022 @11:02AM (#32800173)
Where do you see the Rust team claiming they will make no breaking changes?

Note: answers like "an anonymous nobody on Twitter says Rust is better than <other language> because it never breaks compatibility" get zero points.

Re:Abstracting over ownership in Rust with higher-rank type ... by umanwizard on Sunday September 11, 2022 @11:08AM (#32800217)
Here is Steve Klabnik, who is on the rust team (or at least used to be), claiming that code that doesn’t compile on a newer language revision “relies on unsound things”: https://news.ycombinator.com/item?id=32063749
Re:Abstracting over ownership in Rust with higher-rank type ... by jmillikin on Sunday September 11, 2022 @11:18AM (#32800338)
That is not what Steve is claiming.

The exact quote is:

  > > code written 5 years ago will often not compile today.
  >
  > citation needed. Yes, there's a few programs that relied on unsound
  > things for which this is true, but that's a relatively small part of
  > the overall amount of code.
In other words, there are a small number of packages that were doing things outside the bounds of what the Rust change policy guarantees -- for example unintentionally relying on type-checking bugs, or unstable features accidentally stabilized, or implementing traits on a struct when the library doesn't control both of them.

This does not mean that Rust code will "often" not compile. It is possible for Steve (and the public at large!) to know this, because the impact of breaking changes are measured by Crater.

The alternative choice, to prevent compiler/stdlib changes from being able to break any valid program, would halt language evolution. We've seen this in languages like C and C++, where the standards bodies make a truly heroic effort to avoid breaking code, but (1) they stop being able to evolve the language, and (2) code breaks anyway because there's always someone who's skirting the edge of permitted extension.

Re:Abstracting over ownership in Rust with higher-rank type ... by umanwizard on Sunday September 11, 2022 @11:26AM (#32800431)
> for example unintentionally relying on type-checking bugs, or unstable features accidentally stabilized, or implementing traits on a struct when the library doesn't control both of them.

One of these things is not like the other. Implementing your own traits on foreign types isn’t “unsound”, it’s an absolutely normal and reasonable thing to do.

Steve specifically said “unsound”, which means something specific. He didn’t say “doing things outside the bounds of what the Rust change policy guarantees”.

Re:Abstracting over ownership in Rust with higher-rank type ... by jmillikin on Sunday September 11, 2022 @11:44AM (#32800590)

  > One of these things is not like the other. Implementing your own traits
  > on foreign types isn’t “unsound”, it’s an absolutely normal and reasonable
  > thing to do.
It's possible to do, and there's good reasons to do it, but you have to be extremely careful about either (1) specifying all method calls unambiguously, or (2) extensive testing for dependency upgrades. It's very similar to wildcard imports, because you're no longer in sole control of the local namespace.

If you choose to let a dependency inject symbols into your local namespace, and that dependency is the standard library, then you're signing yourself up to have every toolchain upgrade be painful.

Think of it as similar to naming C/C++ types with leading underscores. Yes, you could have gotten away with `typedef int _Bool;` for decades, but eventually the standard library will call that bet.

  > Steve specifically said “unsound”, which means something specific. He
  > didn’t say “doing things outside the bounds of what the Rust change
  > policy guarantees”.
It seems like you're interpreting "unsound" in a sense similar to "violates type-safety soundness", but I don't think that's what Steve meant and it doesn't seem like a reasonable interpretation.
Re:Abstracting over ownership in Rust with higher-rank type ... by umanwizard on Sunday September 11, 2022 @12:36PM (#32801062)
> Think of it as similar to naming C/C++ types with leading underscores. Yes, you could have gotten away with `typedef int _Bool;` for decades, but eventually the standard library will call that bet.

_Bool and all other names beginning with an underscore followed by a capital letter are explicitly reserved by the C++ standard.

Thus writing “typedef int _Bool” in user code is in fact unsound.

> I don’t think that’s what Steve meant

It’s actually quite clear what he meant, because “unsound” is a term of art in the Rust community and usually means something like “code that can be used in a way that invokes undefined behavior”. His explanation elsewhere in this thread of what he meant agrees with my interpretation, not yours.

Re:Abstracting over ownership in Rust with higher-rank type ... by pjmlp on Sunday September 11, 2022 @02:48PM (#32802195)
In C23 bool is a proper type now.
Re:Abstracting over ownership in Rust with higher-rank type ... by steveklabnik on Sunday September 11, 2022 @07:24PM (#32804217)
I’m not sure why you’re downvoted here. While it’s true I mentioned unsoundness in my comment, when talking about this I do mean it in the senses you are talking about. It’s just that, as you correctly identified in your first reply, the original assertion is that most programs do not compile, and that specific example is the most straightforward way to acknowledge “yes, it is true that there are non-zero programs which compiled in 1.0 that do not compile today.” Soundness issues aren’t the only example, as I alluded to in my other reply done there, just the easiest one to acknowledge that it’s non-zero. But as also repeated above by both myself and burntsushi at least, the team doesn’t take a “well we said we could” approach to breakage; if breakage would be significant, the rust project either does it another way or doesn’t do it. This means that I believe, as you say, that the original assertion isn’t right. Most programs do still work.

I didn’t get to it in my other comment, but I appreciate your work clarifying in this thread previously; I didn’t see I was mentioned until well after you had made some comments. You did explain the gist of what I was getting at. I wish people wouldn’t suddenly start downvoting someone because they believe you’re wrong all of a sudden.

Re:Abstracting over ownership in Rust with higher-rank type ... by steveklabnik on Sunday September 11, 2022 @12:27PM (#32800989)
When I wrote the comment being discussed here, I was thinking of the sibling RFC to the one burntsushi linked above, the one for the language instead of for the library: https://rust-lang.github.io/rfcs/1122-language-semver.html

> This RFC proposes that minor releases may only contain breaking changes that fix compiler bugs or other type-system issues. Primarily, this means soundness issues where "innocent" code can cause undefined behavior (in the technical sense), but it also covers cases like compiler bugs and tightening up the semantics of "underspecified" parts of the language (more details below).

But more importantly, the next paragraph:

> However, simply landing all breaking changes immediately could be very disruptive to the ecosystem. Therefore, the RFC also proposes specific measures to mitigate the impact of breaking changes, and some criteria when those measures might be appropriate.

This has been invoked before; early on in Rust's life, https://rust-lang.github.io/rfcs/1214-projections-lifetimes-... fixed a soundness bug, and as it says

> Warnings first, errors later. Although the changes described in this RFC are necessary for soundness (and many of them are straight-up bugfixes), there is some impact on existing code. Therefore the plan is to first issue warnings for a release cycle and then transition to hard errors, so as to ease the migration.

While the RFC says "a release cycle," that was optimistic. Version 1.4.0 (2015-10-29) introduced the warnings, but the warnings didn't turn into errors until Version 1.7.0 (2016-03-03).

This was intentional breakage that did break programs, for good reason. Those are programs that could have compiled on Rust 1.0 but deliberately do not past 1.7.0.

While it is also true that there are tiny things that technically would break code in many releases, these are only allowed because they're very small things that measurably do not have an impact. They're theoretically breaking, or would be breaking in a different universe where people had written different code that relied on it. Or that is considered acceptable via the API evolution RFC.

But in practice, those changes just aren't experienced by Rust programmers as "breakage." In the 2021 survey, only 2% of users disagreed with the statement "I can upgrade the stable compiler version without fear of my code failing to compile." That isn't even saying "Did it break your code"; it's talking about how users feel about this. 2%! If you go with the closer question, "Upgrading to a new stable compiler version requires either no changes or extremely small and easy changes to my code," only 1% disagree. The data provided doesn't provide more granularity than a percent, so I don't know how it's rounded. But in terms of "is the Rust Project causing users pain with breaking changes?" the answer is very clearly "no."