Cessen's Ramblings

2018 - 12 - 12

Rust 2019 - It's the Little Things

(This post is in response to this call for posts on the Rust blog. Also, this post focuses on Rust as a language, because I feel like the crates ecosystem is something that will naturally grow and mature over time as more people use Rust for more use-cases. Also, in most respects I agree strongly with Jonathan Turner's Rust 2019 post, which has a similar flavor to this one.)

This might be an uncommon opinion—especially among those motivated enough to write a Rust 2019 post—but I actually think Rust is pretty much at a good place now. For the kinds of things that I want to do (e.g. my path tracer), there isn't much that Rust is lacking as a language. There are some fiddly things like "placement new" that could be useful, but nothing really major. And of course, well-designed new features are always welcome, they just don't seem particularly critical to me at this point.

In other words, I'm pretty much satisfied. Mission accomplished, as far as I'm concerned. I think the rest is just polish. Just the little things.

But... the little things aren't necessarily little in terms of effort and hours needed to accomplish them. I don't think any of the following is trivial. I mean "little" with respect to shininess and visibility/marketing optics. Also, little != unimportant here.

So without further delay, these are the things I would like to see Rust focus on in 2019.

Type-level Integers (a.k.a. Integers as Generic Arguments)

This paper cut is pretty easy to run into. I was at the Seattle Rust Meetup this month, and while helping out a new rustacian we ended up stumbling over the list of impls for fixed-size arrays in the standard library. It's... silly. Tons of impls that are identical except for varying the length of the array. I felt like I had to apologize to the person I was helping, "Yeah... yeah, it's super stupid. Yeah, I'm sorry. Yeah, you're totally right. There are plans to improve the situation. No, I'm not sure when, or how far along it is. But you can work around it this way."

I realize that allowing values of (almost) any type as generic arguments is a seductive and appealing idea. But from my perspective, Rust already has type-level integer arguments, in the form of fixed-size arrays. It's just that users don't have access to them for their own types, nor for impls of their own traits over arrays. It's a lot like how Go has built-in generic maps, etc. but you can't make your own generic types in it. There's this sort of implicit acknowledgement in the language design that "this is useful to be able to do", but at the same time it doesn't let you do it yourself.

So I think that just focusing on pushing type-level integers across the finish line should be a goal for 2019, without all the complications of more general type-level values. It's a long-standing paper cut that feels like a missing feature, rather than a wish-list new feature. It makes Rust feel inconsistent, and has concrete, negative, practical impacts even in the standard library itself as per the link above.

Expanding Supported Architectures

This isn't directly interesting to me—I'm pretty happy in x86/x64 land. But moving more architectures to the higher support tiers seems like it would be good. Rust is a "systems" programming language, and even though people don't seem to agree what "systems programming" means any more than they agree on what "art" means, I nevertheless think having a rich set of well-supported architectures is worth aiming for in a language like Rust. It would be nice if people didn't have to reach for C or other memory unsafe languages just because they're targeting a different chipset.

Compile Times

This is a boring topic to bring up, but Rust's compile times still leave a lot to be desired. I am really pleased with the progress already made, and in no way mean to belittle that or the efforts that have led to that progress. It's more to say: more please! I think this is actually really important. Performance matters. In fact, caring about performance is one of the reasons for using Rust, right? So I think prioritizing performance and other not-so-shiny things (as opposed to e.g. new features) for 2019 might be worth considering.

In Short...

This is all to say: I think Rust is great, and I'm actually really happy with where it's at now. I realize that my use-cases are not the same as everyone else's (e.g. I don't personally have much use for async/await). But there are a lot of little things that I would like to see some focus put on. That is my hope for 2019: the year of polish. Not shiny new features, not even ergonomics improvements per se as in the previous cycle. But polish on technical items.

Rust 2021 Edition

As for the possible future Rust 2021 Edition... well, this may also be an uncommon opinion, but I hope we don't have one. Frankly, I hope we don't ever have another edition of Rust at all. I hope 2018 is the first and last one.

That may seem harsh, but let me clarify: Rust 2018 was absolutely a good thing, and I'm glad that we did it. But it was also a bad thing, in that it makes the world of Rust more confusing.

This was highlighted for me at the recent Seattle Rust Meetup, where a new user couldn't get his code to compile. I also struggled to figure out why while helping him. Eventually someone else came by and asked, "Is this in Rust 2018?" We checked, and indeed the new project was Rust 2018, but his code was written in Rust 2015 style in a way that caused an error in 2018 (I don't recall how anymore).

Rust 2018 is backwards compatible in the sense that the compiler can still build 2015 code, and even use both 2015 and 2018 crates together. This is an impressive feat, and a great way to move forward with breaking changes. But technological compatibility is not the only important kind of compatibility.

All of the articles and tutorials on Rust, all of the Stack Overflow questions and answers, and really anything written about Rust at all is now not only out of date but incompatible with the user's first out-of-the-box experience. We went through this once already with Rust 1.0. It's not a good thing. It's quite bad, actually. And I would really, really like to avoid doing it again.

So what I really meant above is not that we shouldn't ever have another edition, but rather that we should try not to. If there are good reasons and things we really want to improve, sure, let's go for it. But let's absolutely not take editions as a given thing, and certainly not as a regular thing.

Let's make new editions only when justified—when the benefits outweigh the drawbacks. Not as part of a cadence. And let's try to make them as infrequent as possible. If we can go ten years without a new edition, I think that should be viewed as a good thing. Editions are a tool we can reach for when needed, but they are a tool with a cost.