4 ms·
> Rust's philosophy, which is to find the best solution to the problems it's trying to solve, at any cost, including breaking compatibility, at least to some de
by jll29 9mo ago
> Rust's philosophy, which is to find the best solution to the problems it's trying to solve, at any cost, including breaking compatibility, at least to some degree.
But the Rust team found a great way to avoid breaking
backward compatibility: old code gets automatically compiled by the old version of the compiler, whereas more recent code is treated with the latest version of the compiler.
That is much better IMHO than carrying that old baggage along in the language that e.g. the C++ folks struggle with, where every half-decade a pile of additive changes get piled on the previous version of the language, and nobody can clean up the old mess.
- muvlon 9mo ago> old code gets automatically compiled by the old version of the compile That's not what happens. You always use the same version of the compiler. It's just that the newer compiler version also knows several older dialects (known as editions) of the language.
- usefulcat 9mo agoAnd it remains to be seen how well this approach will work as time passes and the number of versions continues to increase.
- maximilianburke 9mo agoWell, there's the 2015, 2018, 2021, and 2024 editions. It's been a decade and it seems to be working pretty well?
- kibwen 9mo agoThat won't be any more of a problem than the support that every existing C or C++ compiler has for targeting different versions of the standard.
- tialaramex 9mo agoRight, it's not considered weird for a C++ compiler to offer C++ 98, C++ 11, C++ 14, C++ 17, C++ 20, C++ 23 and C++ 26 (seven versions) and support its own extra dialects. It is also usual for the C++ compilers to support all seven standard library versions too. Rust doesn't have this problem, the editions can define their own stdlib "prelude" (the reason why you can just say Vec or println! in Rust rather than their full names, a prelude is a set of use statements offered by default) but they all share the same standard library. core::mem::uninitialized() is a bad idea and we've known that for many years, but that doesn't mean you can't use it in brand new 2024 Edition Rust code, it just means doing so is still a bad idea. In contrast C++ removes things entirely from its standard library sometimes because they're now frowned on.
- publicdebates 9mo agoSure, Rust can compile old code. But you can't upgrade that old Rust code to new Rust code very easily. The fact that C was effectively "born old" means you can take a C89 program and compile it as C23 and it should simply work, with extremely minimal changes, if any. That's a killer feature when you're thinking in decades. Which SQLite is.
- alexpadula 9mo agoTrue that!
- vlovich123 9mo agoNo not true. cargo fix —edition automatically does most translation to the new edition (most people never see it fail, I’ve seen it fail only on some obscure constructs that it couldn’t do automatically because the meaning of some trait stuff changed subtly but took 2 minutes or less to fix). cargo clippy —-fix will automatically apply linter fixes or warning fixes when it can. Claiming that editions are an example of rust failing back compat shows a complete ignorance of the ecosystem or what coding in the language is actually like. People in this thread think you can’t mix n match editions or that migrating is some huge unavoidable obstacle. Indeed I have less fear upgrading editions than I do bumping the version of the c or c++ language or even using a newer compiler that exploits accidental UB that had been lurking.
- okanat 9mo agoMy company maintains a medium set of Rust programs deployed on embedded Linux systems. Most of the time the migration is automatically done for you by Cargo itself with the command `cargo fix --edition`. I don't know where you got this impression but our switches from 2018 to 2021 and now 2024 editions went very smootly. Rust hasn't broken backwards compatibility in any bigger way since 1.0.
- LexiMax 9mo agoYou would need to be incredibly careful with compiling old C89 code on a modern compiler. It's not the language changes that would get you, it's a change in how compilers treat undefined behavior. There has always been undefined behavior in C, but back in the day, compilers were nowhere near as aggressive in taking advantage of it to make your code faster. Most C programmers tended to treat C as portable assembly and not a language with rules that needed to be respected for it to not blow up your code. I remember this being endlessly groused over by grognard, traditionalist C programmera, and more than a few of them switched to C++ as a result. After all, if the language was going to be a stickler about correctness, they might as well use a language with the features that meant they didn't have to reach into that bag of tricks.
- AnimalMuppet 9mo agoThis may have its own landmines. Worst case, old code getting compiled in the old way could mean that the exact same line means different things depending on which file it's in. (I don't know whether it is possible with how Rust does this.)
- tialaramex 9mo agoThere are several edge cases where that's exactly what happened. But in all the cases I can think of, when you look at that Rust today, what it meant in say 2018 Edition seems silly, "Oh, that's a daft thing for that to mean, I'm glad it doesn't mean that now" We can't magically step into a time machine and fix how it worked at the time, any more than we could go back and cancel those minstrel shows which now seem awful. We can only fix it now and Rust's editions enable this, without the cost of making old code not work in old projects. for dog in array_of_dogs.into_iter() { /* In Rust 1.0 we get an immutable reference to each dog from the array */ /* But today (since 2021 Edition) we get the actual dogs, not references - thus consuming the array */ } One of the changes I'm looking forward to from a future Edition is what happens when I write native ranges like 1..=10 (the integers 1, 2, 3, 4, 5, 6, 7, 8, 9 and 10). Today this means core::ops::RangeInclusive but that type isn't Copy, because it is Iterator. Instead hopefully one day it'll become core::range::RangeInclusive which is Copy, and so can't be Iterator but instead IntoIterator. So in that future Rust edition (when/if it happens) I can treat 1..=10 the same way as a pair of numbers (1,10) or an array of two numbers [1, 10] which are both Copy, that is, by just copying the bit pattern you are guaranteed to get an object which means the same thing, making life easier for programmers and the compiler. Today, because it isn't Copy, I must do extra busy work, which is slightly annoying and discourages use of this otherwise great type.