1. 52

  2. 13

    I really like how the Rust edition system makes it possible to improve the language in a way that breaks backwards compatibility, while still making it possible to continue to use and maintain old code in a clean way. None of the proposed changes jump out at me as drastically changing my Rust workflow, but they seem like generally good ideas and it would be good to get them into the standard version of the language.

    1. 4

      So I never really understood, how does the edition system improve on just having programming language versions?

      1. 31

        With programming language versions code that works in one version does not work in another (such as python 2 and 3). With Rust editions each library (or crate in Rust parlance) chooses which edition to be compiled with, so you can continue to use libraries written in, say, the 2015 edition while writing code using 2021 edition Rust.

        1. 2

          That makes a lot of sense! Thank you

    2. 5

      This one feels boring to me compared to 2018, which is exactly what I was hoping. After the 2018 edition, a few prominent companies were very clear to the Rust team that if the same thing happened every 3 years, that Rust would not be a sustainable choice for their long-term projects.

      1. 11

        Fun fact, this edition is just as big as the previous one!

        The Rust team has IMHO made a mistake of making one big marketing push under “2018” umbrella for two very different things:

        1. Breaking changes in the 2018 edition, which were actually quite small

        2. Advertising all 2015-compatible features added in previous couple years to highlight the progress Rust has made since 1.0

        And this has created a wrong impression as if everything was suddenly added at once, breaking, and hidden behind the edition flag. When in fact that was multiple years of small backwards-compatible changes, almost all of which are available in all editions.

        The 2018 edition compilation flag only changed:

        • Reserved async, dyn and try as keywords
        • Changed meaning of use paths slightly
        • Elevated a few warnings to errors

        All other changes were not related to the edition, and were added backwards-compatibly to the 2015 syntax (except async syntax sugar, because of the new keyword, but all the underlying std::future machinery works in 2015 edition too). Most of them were released even before 2018 was announced and re-advertised them as new again.

        1. 1

          Excuse the flippant reply, but so what? The value of Rust is not determined by mega corps.

          1. -1

            Sorry for my rather flippant reply, but – so what? How is this relevant, and why would people care?

            Is this some US thing where corporations are people, so everyone has to take care to not hurt their feelings or something?

          2. 2

            Blazing hot take: this is the one to rename the type keyword to typedef (yes, I know, more churn than the whole butter industry, but still worth in my view)

            1. 2

              As a very casual Rust user, I don’t really know what these proposed changes might mean to me, but I’m excited about this nonetheless! I do have to say that really appreciate Rust’s stability and it’s improvements over the years. I was hoping to see some mention about interoperability with Result and Option when using the error handling ? operator, but on second thought, I guess features like that aren’t tied to editions!

              1. 8

                Right, the things that are tied to editions are things which would be breaking changes, but which don’t break interoperability (code from all editions must be able to call each other and compile/link together). Adding things to the prelude, for example, is fine in an edition.

                As for what these things mean concretely (assuming things land as described here):

                1. You’ll be able to implement TryFrom and TryInto without needing to use std::convert::{TryFrom, TryInto} first.
                2. You’ll be able to call things like Vec::from_iter(some_iterator) without use std::iter::FromIterator.
                3. Closures which previously may not have worked, or may have required cumbersome code to work around because they captured a whole struct when you only needed part of it, will be possible or simpler.
                4. Resolving features for dependencies with Cargo will be more powerful and flexible.
                5. A bunch more small stuff.
              2. 1

                Another edition? I love rust, but this is starting to feel silly…

                1. 15

                  What? This is only the second edition. Did you think there was only going to be one edition?

                  1. 14

                    This one will also be coming out 3 years from the last one. Hardly seems too fast; this is the same pace for new versions as C++.

                    1. 6

                      C++ is a famously overcluttered language. I’d prefer not using it as a complexity benchmark for rust. However I also don’t object to the three year edition cycle.

                      1. 1

                        3 years is likely not even enough time for some large peojects to migrate to the previous edition. With a 3-year cycle there will be pressure for any large rust user to effectively constantly be updating. 10 years would be a better minimum.

                        1. 8

                          Edition migration is a job for one afternoon, not 10 years. It’s trivial. If your code compiled without warnings, it’s just a matter of prefixing a few things with r# or crate::. cargo fix does it automatically anyway.

                          Don’t confuse edition-incompatible changes (which are few and small) with adopting new functionality added over these years. You don’t need to rewrite your code to use fancy new async/await just to enable a new compilation mode.

                          Also it’s not an all-or-nothing switch for entire projects and their dependencies, like Python 2->3 was. Rust allows mixing editions, so you update one crate at a time.

                      2. 1

                        No, but I hoped for a more reasonable speed to introduce breaking changes. It’s only 3 years since the last one!

                        1. 3

                          From https://doc.rust-lang.org/edition-guide/editions/index.html:

                          When a new edition becomes available in the compiler, crates must explicitly opt in to it to take full advantage. This opt in enables editions to contain incompatible changes, like adding a new keyword that might conflict with identifiers in code, or turning warnings into errors. A Rust compiler will support all editions that existed prior to the compiler’s release, and can link crates of any supported editions together.

                          In other words, there are no breaking changes, there are changes one can opt in to enjoy the new shiny things, and the editions are promised to be supported and compatible “indefinitely”.

                          1. 1

                            enales editions to contain incompatible changes

                            It’s right there in the quote :) Yes, a large project could stay on the previous edition, but there will be pressure to move, and more pressure as each new edition comes out and they are perceived as being “further and further behind”. This is the same thing that happens with other opt-in language version ecosystems (haksell, C, C++, probably others)

                            1. 7

                              The pressure to stay up to date with language idioms and latest dependencies is real, but it’s a separate thing from enabling an edition flag in Rust.

                              Editions are different from C++ versions! In C++ new features aren’t added to old versions, e.g. C++98 is frozen in time and hasn’t changed since 1998. This is not the case in Rust! Every new feature in Rust is added to all past Rust editions, as long as it’s possible (i.e. it doesn’t require a keyword added later). For example, the new 2021 const generics feature that will be released this month is available in the Rust 2015 edition.

                              Rust editions are closer to "use strict"; in JS. There’s one Rust with one feature set, one standard library, and there are different levels of warnings vs errors and minor syntax variations to keep old programs compile with no changes.

                              Switching on Rust 2018 edition just boils down to tiny things like “I’m not using async or try keywords for my functions/variables”. You just rename variables if you did, and off you go!