11 ms·
The Plan for the Rust 2021 Edition
- nynx 5y agoThis doesn't require an edition change, but I'm really looking forward to custom, per-collection allocator support. It's in nightly right now and very nice to use.
- swsieber 5y agoThere's been a lot of attention given to the api since the roll-out: https://internals.rust-lang.org/t/is-custom-allocators-the-right-abstraction/13460/88 https://internals.rust-lang.org/t/is-custom-allocators-the-r... I'm not sure if the changes discussed there are going to be rolled in or not. It's certainly an interesting thread.
- nynx 5y agoYeah, I’ve been following that thread. The storage idea is interesting but I don’t think it’s really necessary. The main thing it would enable is inline allocators that can be stored inside the collection, as opposed to the collection storing a reference to the stack allocation. The cases where that’s necessary, one can use the stackvec or arrayvec crates, which are more optimized than a generic inline allocator would be anyhow.
- dmkolobov 5y agoLack of IntoIterator for arrays and disjoint capture are some of the biggest pain-points in writing Rust code for me! Very excited to see these changes on the map.
- Flex247A 5y agoReally excited to see the syntax becoming more consistent! I am looking forward to master Rust in the coming 4-5 years.
- axiosgunnar 5y agoSince you said „master“ you are probably already somewhat proficient, but if not, I can not recommend enough to just try Rust out for some project one day. It literally took me 2 days from writing my first line of Rust to having a central component of our pipeline rewritten in Rust and running in production and I enjoy every minute of writing Rust, since (after you win the battle with the borrow checker) everything „just works“.
- throwaway894345 5y agoI also like writing Rust, but “After you win the battle with the borrow checker” is doing a lot of work. Those battles often crop up unexpectedly and sometimes they’re easily resolved and other times they require reworking your architecture—it’s very hard to estimate how long it will take. Of course, there are escape hatches—you can clone excessively, but it’s not all peaches and cream.
- whatshisface 5y agoAbout 80% of my battles with the borrow checker eventually resolve with me realizing the code I'm trying to get working could lead to a bug in a case I hadn't considered. Of course, I could just be an abnormally sloppy programmer.
- throwaway894345 5y agoIn my experience, borrow checker errors would only be “bugs” in a program that doesn’t have a garbage collector or if there is shared memory parallelism involved. Put differently, if you slapped a borrow checker on Go and your program was single-threaded, (I posit but welcome correction) borrow-checker errors would probably not be uncovering many bugs.
- dj_mc_merlin 5y agoYes, the point of the borrow checker is memory safety without GC.
- asimpletune 5y agoI love how subtle and thoughtful these changes are. Rust isn’t only a great language, it’s a model of how technology can be built.
- throwaway894345 5y agoAgreed. And I'm not sure if this is more or less precise than "model", but I often think about Rust as a process and community for developing a programming language, rather than as a programming language itself. This seems related to your 'model' remark.
- brundolf 5y agoIt's amazing how perfectly they're able to balance pragmatism with idealism/principles. For me that might be the defining trait of this language and community; most languages swing too hard in one direction or the other.
- api 5y agoThese seem pretty minimal. Most of the code I can recall writing or have seen would require no changes or maybe a one liner here and there.
- nindalf 5y agoThe 2018 edition came with tools to automate the migration. I imagine most of these changes will be fully automated as well.
- raphlinus 5y agoI think that's a good thing. People do complain about the overly high rate of evolution of Rust, but I think that was much more true in previous years than today (not least because a lot of projects needed to depend on nightly). Also, most of these changes enable new things, and are only in the edition because of some low chance of breaking existing code. The 2018 edition had some major changes, so 2018 code looks pretty different - the ? operator, big changes to module use, impl/dyn Trait, and more. I suspect that most code bases you won't be able to tell whether it's 2018 or 2021 without looking more closely.
- chrismorgan 5y agoI expect a common complaint to be “why isn’t [].into_iter() working in my tests? —oh, it’s 2018 edition”, though this can be mitigated by a specialised error message which didn’t exist last week when I first learned about this matter.
- ckok 5y agoBut that's the right way to do it really... I remember an obscure thing in c# when var was introduced that if you have a type called 'var' in scope, type inference doesn't work and it uses that type instead. This is the way new features should be introduced.
- sodality2 5y agoI am actually excited to learn rust as I try to learn lower level languages. Not so for any other language.
- tdhz77 5y agoI’m with you, but I wonder if it’s because I get a lot of my tech pulse from hacker news and the community for right or wrong seems so bullish. In my experience it was cool. I was impressed with the speed. I tried to make a cryptocurrency (non-distributed) and that was cool. I don’t think in low level yet, but I’m trying to figure it out.
- fastasucan 5y agoSame for me. I have no idea why, but it excites me to learn rust. Maybe because it have a so obvious source to learn from (The book), and that it still is fairly a new and "limited" language? I can't wait to get some major work-hurdles out of the way so I can go through the book. Not sure if I'll use Rust that much professionally, but my experience so far is that I learn so much about programming while I am learning it.
- tvb12 5y agoI thought this post was about the book, rather than the language. The book is supposed to be up to date for Rust 2018. I suppose there's probably no need to wait for the book to catch up to the language.
- steveklabnik 5y agoWe will update the book, but only after the changes are finalized :)
- RcouF1uZ4gsC 5y ago> However, note that Rust is a project run by volunteers. We prioritize the personal well-being of everyone working on Rust over any deadlines and expectations we might have set. This could mean delaying the edition a version if necessary, or dropping a feature that turns out to be too difficult or stressful to finish in time. What a refreshing take! One of the things I have admired about Rust is the effort from the start to build a healthy, welcoming, non-toxic community, and to prioritize personal well-being.
- kbenson 5y agoYeah, a lot of communities work this way implicitly, but being explicit about it likely has some nice mental health benefits in itself, as even if most people people are totally understanding, sometimes the person themself needs it explicitly said that it's okay for them to just back off for a bit and they aren't letting everyone down. Sometimes it's our own expectations and beliefs that drive us the hardest when we need a break.
- mathw 5y agoI would say it's very important to be publicly explicit about it, to help with the expectations of people outside the project. If some of these things then don't make it into 2021, or 2021 is delayed a bit, that wonderful paragraph can be pointed to as part of the explanation. Plus of course it gives people on the project more confidence in saying "I have to have my evenings to recharge, I can't crunch this feature to hit the deadline". Which is what we should all be able to say.
- yakubin 5y agoOne thing that I repeatedly bump into in Rust is the oddity of multi-argument functions. To explain the problem, let's look at another language for a moment: in SML there is no such thing as multi-argument functions per se. There are two ways to write them anyway: * the function's argument is a tuple (this is the more common way, not only in SML, but also how it's done most commonly in maths); * currying. I'm not a fan of currying, because it singles out the first argument over the others. However, the first approach (tuples) is very ergonomic, because now you can pass the return value of one function as an argument to a "multi-argument" function. One application of that is function composition. But another is a simple map. I've lost count of how many times in Rust I had an "o: Option<(A, B)>" and a "f: fn(A, B) -> C" and couldn't call "o.map(f)"; instead the programmer is forced to write more noisy code with lambdas. And lambdas sometimes don't play well with the borrow checker for mysterious reasons (even those that don't capture anything). Also, I think it would be nice if the compiler generated named discriminants for every enum. Currently, "std::mem::discriminant" returns an opaque "std::mem::Discriminant<T>" (which doesn't have a name). In order to compare discriminants I need to create a full-blown enum value and extract the discriminant from it later. I've worked around this problem by using the "strum" crate, which has a macro to produce another (plain) enum, but having the discriminant type be named "std::mem::Discriminant<T>" (to signal the connection to the original enum) and have named variants at the same time would be the best of both worlds. EDIT: If I knew more about possible breakage caused by my first suggestion, I could probably start working on an RFC. However, I feel I don't have enough knowledge about Rust to anticipate that. For my second suggestion I think I'm going to try to propose that. I'm reading the docs on the process now.
- nynx 5y agoHaving enum variants be structs has been proposed, and that could solve your issue if `mem::disciminant<Enum::Variant>` returned what you wanted.
- yakubin 5y ago> Having enum variants be structs has been proposed That's great news. > that could solve your issue if `mem::disciminant<Enum::Variant>` returned what you wanted. I think you misunderstood, or I explained it poorly. Given an: enum Enum { A(int), B, } I would like mem::Discriminant<Enum> be the same type as if there was such a definition in code (illegal in Rust, because Rust doesn't have specializations): enum mem::Discriminant<Enum> { A, B, }
- maxioatic 5y agoThis little bit, which is not coming in this version but is enabled by it: > f"" as a short-hand for a format string. For example, f"hello {name}" as a short-hand for the equivalent format_args!() invocation. I'm excited by. I like the f-string formatting in Python quite a bit.
- throwaway894345 5y agof-strings in Python resolve to strings, but f-strings in Rust will resolve to std::fmt::Arguments IIUC. Not quite the same thing.
- kibwen 5y agoYes, there's a lot of small details that need to be ironed out before we get a clear picture of what the feature might be (remember, there's no guarantee!). There's a reason this is simply reserving the syntax, rather than actually proposing the feature. :)
- throwaway894345 5y agoOf course, I didn't mean to imply any certainty, only that the blog post mentioned that it would likely resolve to format_args! which doesn't return a string but rather std::fmt::Arguments.
- steveklabnik 5y agoOur original formatting was inspired by C#, this is inspired by Python. We stand on the shoulders of giants, as always.
- Macha 5y agoDidn't realise the C# intermediate step was there, always assumed it was a direct Python influence.
- steveklabnik 5y ago
- markwisde 5y ago“We can’t add tryinto to the prelude, as a solution we’re adding tryinto” What?
- steveklabnik 5y agoYou cropped out the relevant part: > As a solution, Rust 2021 will use a new prelude. That is, we cannot add it into the existing prelude. But we could have a new prelude, tied to the new edition.
- Animats 5y agoShouldn't more of those prelude items be in "core", rather than "std"? Many involve neither I/O nor allocation.
- TheCoelacanth 5y agoAll of the new items are in "core", e.g. https://doc.rust-lang.org/core/convert/trait.TryInto.html https://doc.rust-lang.org/core/convert/trait.TryInto.html
- 3836293648 5y agoEverything in core is also in std. You only link to anything in core in a no_std context (or if you do it explicitly for some reason)
- markwisde 5y agoI don’t see how this solves the issue of colliding with a user-provided tryinto
- msbarnett 5y agoIt solves the issue by not breaking any existing code that doesn't explicitly opt in to the new edition.
- qzw 5y ago> Instead, we decided to add the [IntoIterator] trait implementation in all editions (starting in Rust 1.53.0), but add a small hack to avoid breakage until Rust 2021. Eh, why not. We nerds are used to retconning in all the sci-fi universes anyway.
- floatboth 5y ago> Starting in Rust 2021, closures will only capture the fields that they use Holy shit yes. Thank you thank you thank you. This fixes my biggest annoyance so far!
- ebingdom 5y agoI love Rust, but one thing that seems like a glaring design flaw is that adding a new trait implementation can change the behavior of existing code. This is very counterintuitive, because it seems like a purely additive change. In my opinion, the convenience of auto-dereferencing "as much as possible" to make method call syntax magically work through the indirection of references is not worth the lack of stability guarantees that it causes. This isn't a normal kind of breakage where the compiler points out what code you need to fix; this is a much worse kind of breakage where you might not even realize your code now behaves differently. In my opinion, the notion of "editions" is not an acceptable solution to this. For a language that prioritizes safety, there are a surprising number of gotchas in Rust (another example is the large number of partial functions in the standard library).
- Arnavion 5y agoA lot of `expr.expr` would need to become `(&expr).expr` or `(&mut expr).expr` if auto-dereferencing wasn't a thing. C++ has `.` and `->` but Rust only has `.` (To be clear, what's happening with `array.into_iter()` is unsize coercion, not auto-dereferencing. `[T; N]` does not impl `Deref<Target = [T]>`. But the point is the same.)
- ebingdom 5y agoI think you have it reversed. `expr.expr` would need to become `(*expr).expr` if we didn't have auto-dereferencing.
- Arnavion 5y agostruct S; impl S { fn foo(&self) { } } let s = S; s.foo(); That compiles today. Your proposal would require it to be `(&s).foo()`
- pcwalton 5y agoIn other words, there is auto-ref in addition to auto-deref, and auto-ref causes the same issues of possibly-surprising method resolution. As I mention above, auto-deref is just one way that methods could resolve to the "wrong" implementation, and there would be no solution that I can see other than to remove dot entirely, which isn't viable.
- RhodoGSA 5y agoDecided to start learning rust last month. I have very little previous programming experience and the journey has been a bit brutal so far so i wanted to share my "Learning journey". "The book" although a great book, is fairly dense with no exercises. Rustlings[1] help me apply alot of my learning and i supplemented the book with Tensors programming tutorials on youtube [2]. Recently i started developing a game in Bevy[3] and although its a bit over my head at this point i've managed to get a character moving and be able to kill a monster and receive a drop. My motivations for learning rust was to be familiar with substrate [4] as i'd like to switch careers into programming. Would also love any recommendations/tips & tricks by any experience rustaceans! [1]https://github.com/rust-lang/rustlings https://github.com/rust-lang/rustlings [2]https://www.youtube.com/watch?v=EYqceb2AnkU&list=PLJbE2Yu2zumDF6BX6_RdPisRVHgzV02NW&index=1 https://www.youtube.com/watch?v=EYqceb2AnkU&list=PLJbE2Yu2zu... [3]https://bevyengine.org/learn/book/getting-started/ https://bevyengine.org/learn/book/getting-started/ [4]https://www.substrate.io/ https://www.substrate.io/
- brundolf 5y agoThis was a crucial part of my learning process; I recommend it to everyone who asks: https://rust-unofficial.github.io/too-many-lists/ https://rust-unofficial.github.io/too-many-lists/
- RhodoGSA 5y agoThanks for this! read through the first couple chapters and it's already plugged some holes that i didn't really understand. Can you point me to some really good rust code on github? I've been reading through some and see how people do some interesting things but i don't have the mastery to understand which practices are better than others.
- bfrog 5y agoCongrats on making a game!
- cema 5y agoI just want to wish you good luck on your journey to software engineering. It is an incredibly satisfying and rewarding experience, and I know that many people who have chosen this path as a career change are happy and successful!
- Traster 5y agoMan I feel like an idiot. I read the first paragraph and I'm like "that's just versions" and then I read the next few paragraphs and I'm like "Yeah but your dependencies are going to screw you". I'm not sold on the raw identifier syntax and we'll see if the changes are actually as good as they claim, but in general this seems like a great way of doing language 'versions'. Rust is definitely learning from the past and I'm really interested see what we learn from how they fuck up too
- steveklabnik 5y agoWe've already done one of these! This is the second introduction of a new edition, and therefore, our third overall: 2015, 2018, and now 2021. If you want to see how it works, you can create a new project, which defaults to Rust 2018, and depend on https://crates.io/crates/semver https://crates.io/crates/semver, which is on Rust 2015, and see that interop works just fine! Yeah don't worry we'll fuck up for sure, haha. One could argue we've made a few of those already...
- kibwen 5y agoNote that the raw identifier syntax is from Rust 2018, not the upcoming edition. Also it's only intended to be used for rare occasions, and even then only temporarily, so it's not a big deal if the syntax is fairly clunky; it just needed to be something that the Rust 2015 parser wouldn't choke on.
- dluan 5y ago> However, note that Rust is a project run by volunteers. We prioritize the personal well-being of everyone working on Rust over any deadlines and expectations we might have set. This could mean delaying the edition a version if necessary, or dropping a feature that turns out to be too difficult or stressful to finish in time. I like this.
- pjmlp 5y ago> It has been suggested many times to "only implement IntoIterator for arrays in Rust 2021". However, this is simply not possible. You can't have a trait implementation exist in one edition and not in another, since editions can be mixed. Another example how editions aren't much different than mixing language versions on other eco-systems, just another way of achieving similar results.
- AnonC 5y agoThe page source for this post has this comment at the end: <!-- If you really can't wait, many features are already available on Rust [Nightly](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html) with `-Zunstable-options --edition=2021`. -->