This is a surprisingly simple to understand introduction for why the never type is/(would be) a good addition for rust. Thank you for posting the reference.
Too bad that they didn't follow the common convention and call it the "bottom" type, because that's what it's called in most other language to my knowledge.
And it's good that Rust has that type. Any language with a decent typesystem must have it. If a language doesn't have it, well, from my perspective it's an amateur language and a world of pain awaits you. Looking at golang for example...
Rust places very high value on not breaking crates in crates.io. Normally, the ability to mix different editions of Rust simplifies this. But there are some deeper changes that editions can't help with. And Rust has a reached a point where many of those changes are difficult or perhaps impossible.
The most impressive part of supporting never is figuring out how to finesse the compatibility issues within Rust's backwards compatibility goals (and presumably convincing everyone you succeeded). Huge congratulations on doing lots of tricky work to get this done.
I was surprised to read the linked bug, which says "sets the never type fallback to ! on all editions (breaking change, [...]". That is to say, this change can break old code despite the edition system?
Writing this comment made me look harder at the bug (I realized I hadn't expanded the hidden comments) so there is more discussion there of why this approach was chosen. It looks like they previously landed a warning detecting the code that this change will break (?).
It's really hard to totally avoid breaking changes, if only because existing code may exploit bugs. One of the things the Rust project has done in the past is use their "Crater" tool to recompile all of crates.io and look for regressions. They have been known to send PRs! In practice, this means I've personally seen maybe 3 minor cases of technical breakage since 2015, all fixed in about 15 minutes on my end. Even coming from a C background, Rust's backwards compatibility often feels unreal.
I don't know how "never" fits into the Rust backward compatibility goals in detail, and if they're accepting a certain level of breakage. I just know that this issue had been blocked for ages, waiting for someone to figure out the corner cases and get consensus behind an approach. I am complimenting them not because I understand exactly which solution they chose, but rather because I know the problem was miserably hard the last time I looked at the discussions.
I clicked through to Waffle's (incredible!) talk this morning, and understand the breaking-issues to have been a long tail of "last 20%" interactions with other features, conventions, and semantics (explicit or implicit) around things like unimplemented, the Unit type, and related equivalences, (esp. where they affect the semantics of a type signature). In practice most crates depend on affected packages, but the number of "roots" were tractable (a couple dozen?) and volunteered or merged fixes. I'm surprised about that, and want to know more too -- we can find gnarly crate-by-crate details in (and linked outed from ;u;) the tracking issue (github). A great overview of related links can be found in the body of the merged PR.
uwaces | 10 hours ago
Thank you for your sustained effort! There are people out here who appreciate your effort!
hawski | 12 hours ago
For the confused: https://doc.rust-lang.org/std/primitive.never.html
siru | 7 hours ago
This is a surprisingly simple to understand introduction for why the never type is/(would be) a good addition for rust. Thank you for posting the reference.
mplanchard | 4 hours ago
I love the Rust docs. I have recently been doing more C++, and every trip into the stdlib docs makes me miss Rust
valenterry | 58 minutes ago
Too bad that they didn't follow the common convention and call it the "bottom" type, because that's what it's called in most other language to my knowledge.
And it's good that Rust has that type. Any language with a decent typesystem must have it. If a language doesn't have it, well, from my perspective it's an amateur language and a world of pain awaits you. Looking at golang for example...
andyferris | 25 minutes ago
Typescript and Python call it “never” and are two of the most popular languages in the world.
I’d say “bottom” is more a PLT term than industrial-language term, myself.
emk | 10 hours ago
Rust places very high value on not breaking crates in crates.io. Normally, the ability to mix different editions of Rust simplifies this. But there are some deeper changes that editions can't help with. And Rust has a reached a point where many of those changes are difficult or perhaps impossible.
The most impressive part of supporting
neveris figuring out how to finesse the compatibility issues within Rust's backwards compatibility goals (and presumably convincing everyone you succeeded). Huge congratulations on doing lots of tricky work to get this done.evmar | 9 hours ago
I was surprised to read the linked bug, which says "sets the never type fallback to ! on all editions (breaking change, [...]". That is to say, this change can break old code despite the edition system?
Writing this comment made me look harder at the bug (I realized I hadn't expanded the hidden comments) so there is more discussion there of why this approach was chosen. It looks like they previously landed a warning detecting the code that this change will break (?).
emk | 8 hours ago
It's really hard to totally avoid breaking changes, if only because existing code may exploit bugs. One of the things the Rust project has done in the past is use their "Crater" tool to recompile all of crates.io and look for regressions. They have been known to send PRs! In practice, this means I've personally seen maybe 3 minor cases of technical breakage since 2015, all fixed in about 15 minutes on my end. Even coming from a C background, Rust's backwards compatibility often feels unreal.
I don't know how "never" fits into the Rust backward compatibility goals in detail, and if they're accepting a certain level of breakage. I just know that this issue had been blocked for ages, waiting for someone to figure out the corner cases and get consensus behind an approach. I am complimenting them not because I understand exactly which solution they chose, but rather because I know the problem was miserably hard the last time I looked at the discussions.
gignico | 10 hours ago
Can you give some examples of the issues that were addressed?
antlers | 9 hours ago
I clicked through to Waffle's (incredible!) talk this morning, and understand the breaking-issues to have been a long tail of "last 20%" interactions with other features, conventions, and semantics (explicit or implicit) around things like
unimplemented, theUnittype, and related equivalences, (esp. where they affect the semantics of a type signature). In practice most crates depend on affected packages, but the number of "roots" were tractable (a couple dozen?) and volunteered or merged fixes. I'm surprised about that, and want to know more too -- we can find gnarly crate-by-crate details in (and linked outed from ;u;) the tracking issue (github). A great overview of related links can be found in the body of the merged PR.gulbanana | 12 hours ago
nice. i look forward to not returning things in a compiler-checked manner
gignico | 12 hours ago
You can already not return empty enums, if you wish :P
schneems | 8 hours ago
I ! thought I would see the day. Congrats
matthew2 | 12 hours ago
Well I never!
adfernandes | 3 hours ago
Just echoing both the sentiment and the thanks…
That is a Herculean effort that will have an enormous impact on a vast swath of computing across and around the world, for many, many years to come.
You are one of the giants whose shoulders others stand on.
mqudsi | 4 hours ago