6 ms·
The documentation is probably the best resource to start with the concept and how it works / what the goals are: https://doc.rust-lang.org/edition-guide/edition
by tubthumper8 2y ago
The documentation is probably the best resource to start with the concept and how it works / what the goals are: https://doc.rust-lang.org/edition-guide/editions/index.html https://doc.rust-lang.org/edition-guide/editions/index.html
For example, https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html https://doc.rust-lang.org/edition-guide/rust-2021/warnings-p... - code that produced a lint warning in the 2018 edition produces a compiler error in the 2021 edition. That would be something that can't be done in a backwards compatible way without editions
Another example would be changes to the import syntax https://doc.rust-lang.org/edition-guide/rust-2018/path-changes.html https://doc.rust-lang.org/edition-guide/rust-2018/path-chang... - the compiler will forever support the 2015 behavior in crates that use the 2015 edition, but crates using newer editions can use the newer behavior
- 9rx 2y agoAs stated before, the documentation in both languages was already consulted. It did not clear up how Rust is any different than Go in this regard. Consider a simple example from the Go documentation: Support for numeric underscores, which was not a part of the original language and later included in a 'new edition' of Go. i := 10_000_000 Using the 1.13 or later version of the gc compiler, if your go.mod specifies anything after 1.12 the above compiles fine. But if go.mod asserts go 1.12 or earlier, you will get a compiler error from the above code as the compiler reverts to 1.12 or earlier behaviour based on the version directive. That sounds exactly like what you described! And, like I said before, Rust's documentation too echoes to my read that editions accomplish basically the same thing and exist for the same reason Go version directives exist. But the earlier commenter indicated that they are very different. So, unfortunately, you have again failed to break the cycle. We need something dumbed down for us regular people, not something directed at those who walk, talk, and sleep Rust.
- tubthumper8 2y agoSorry to have disappointed you. I don't walk, talk, or sleep either Rust or Go, but was trying to provide some resources to help in case you hadn't seen them yet. One difference I noticed in the docs is in the Go Reference it says the "go" line of the "go.mod" has to be greater than or equal to the go line of all that modules dependencies, if the go line is 1.21 or higher, so a module for 1.21 can't depend on a module for 1.22 [1] That restriction doesn't apply for Rust, a library using the 2015 edition can use a dependency that uses the 2018 edition, for example. That's just one difference I noticed in the implementation. The goals seem very similar if not the same [1] https://go.dev/doc/modules/gomod-ref#go https://go.dev/doc/modules/gomod-ref#go
- 9rx 2y agoThanks for trying. But it is the "which is very different to what go has now settled on" that we are trying to get to the bottom of. It appears from your angle that you also conclude that Go has settled on the very same thing, frivolous implementation details aside. Hopefully phire will still return to dumb it down for us.
- phire 2y agoOk... the only thing that go version directives do is selectively enable new features. Essentially, they are only really there to help you ensure your code will continue compiling in older versions of the compiler. Hell, until recently it wouldn't even throw an error if you tried to compile code with a future version directive. The actual backwards compatibility in go is achieved by never removing functionality or syntax. New versions can only ever add new features/syntax. If there was a broken function in the API, that function needs to stick around forever, and they will be forced to add a second version of that function that now does the correct thing. So, you can take code written for go 1.0, slap on a "go 1.23" directive and it will compile just fine. That's the guarantee that go provides. Well, mostly. There are a few examples of go 1.0 code that doesn't compile anymore, even when you use a "go 1.0" directive. But not being able to remove anything ever is limiting. A good example of how this can be limiting is reserved keywords. Go has a fixed set of reserved keywords that they picked for 1.0, and they can never reserve any more, any code using them as identifiers will break. Any new feature needs to be carefully designed to never need a new reserved keyword. Either they reuse an existing keyword (which c++ does all the time), or they use symbols instead. But rust can reserve new keywords. The 2018 edition of rust reserved "async" and "await" for future async functionality and "try" for a potential try block. Rust did reserve "yield" from the start for generators, but decided they needed a way to mark a function as a generator, so in the 2024 edition, "gen" is now a reserved keyword, breaking any code that uses gen as a function/variable name. Do note that rust also follows the go strategy within an edition. There is only one new edition every three years, and it would be a pain if all new features had to wait for a new edition. So the async/await keywords were reserved in the 2018 edition, but didn't actually get used until the end of 2019. This means that just because your rust version supports the 2018 edition, doesn't mean it will compile all 2018 code. The editions are just for breaking changes, and there is a seperate minimum "rust-version" field that's somewhat equivalent to go's "go 1.x" directive. Though, "rust-version" doesn't disable features, it's just there to provide a nice clean warning to users on old compilers. Ideally in the future it will gain the ability to selectively disable language features (as rust already has extensive support for selectively enabling experimental language features in nightly builds, which we haven't even talked about here). Basically, rust editions allow all breaking changes to be bundled up and applied once every three years. They also provides a way for compilers to continue supporting all previous editions, so old code will continue to work by picking an old version. While go's version directive looks superficially similar to editions, it is there for a different reason and doesn't actually allow for breaking changes.