
Rust's 2018 roadmap - steveklabnik
https://blog.rust-lang.org/2018/03/12/roadmap.html
======
smoe
I started learning Rust over the weekends and I think the second edition "The
Rust Programming Language" is among the best introductory books on a
programming language I have read (well half way so far).

As someone not only new to Rust but also systems programming in general I
especially appreciate that the chapters include actual reasoning about why
things are how they are in Rust and that they seem pretty open about drawbacks
of the choices. As well as the use of precise language instead of trying to be
too cute and overly beginner friendly.

An example for this is the lengthy page on Strings: [https://doc.rust-
lang.org/book/second-edition/ch08-02-string...](https://doc.rust-
lang.org/book/second-edition/ch08-02-strings.html)

It really makes me feel you want me to understand what I'm doing from the
start instead of getting a generic app out of the door as quick as possible
and then tediously figure out the next basic steps from screencasts, scattered
blog posts etc.

Also big plus for having the book and api doc available offline by default!

I'm going to try to come by #rustdoc and see if there something I could
contribute.

~~~
jhoechtl
> An example for this is the lengthy page on Strings: [https://doc.rust-
> lang.org/book/second-edition/ch08-02-string...](https://doc.rust-
> lang.org/book/second-edition/ch08-02-string..).

I don't know how the 2nd edition of the book deviates from the first one, but
as you mention the strings section: I had installed rust with rustup,
configured my editor environment, bookmarked and read tutorials and was
serious about learning rust, dabbling with code snippets.

It was the exact chapter you mentioned, strings, which drew me away from rust
in disgust. Four string types ... for the beginner? Seriously?

~~~
neurotrace
Where are you seeing four string types? As far as I know, there's only
`String` and `str`. Heap allocated vs. stack/statically allocated. There's
also things like `CString` and `OsString` but I don't think I've had to deal
with those. If so, it was so similar to working with any other string that I
didn't even notice.

I'm still relatively new to Rust but this is my understanding. Please correct
me if I'm wrong.

~~~
Rusky
> Heap allocated vs. stack/statically allocated.

`str` is very rarely stack allocated, and often points into a heap-allocated
`String`. Further, there's an optimization on the table that will let
`String`s point to static allocations.

The distinction is rather owned vs borrowed. A `String` is in charge of the
memory it uses, so it can grow it by reallocation, free it when it goes out of
scope, etc. A `str` is not in charge of the memory it uses- it's only a
pointer into some memory that something else owns, whether that's a static
allocation or a `String` or some other data structure.

~~~
eeereerews
A `str` is just an unsized blob of UTF-8 data. It's `&str` that is the (fat)
pointer.

~~~
Rusky
You're right; I kind of left that out since it's not (currently) possible to
have a bare `str` anyway and there are more ways to work with one than just
`&str` (`Cow<str>`, `Box<str>`, `Rc<str>`, etc).

------
pimeys
I've been spending a good majority of my work hours with Rust and especially
writing network services using Tokio. When things work there, it is very
reliable, fast and has a tiny footprint with resources.

Now reading the promise to get a stable async/await and also having Tokio 0.2
in the pipeline, I'd say async Rust might be ready for prime time.

Don't get me wrong here, I enjoy using Tokio, but I'd say if you're not very
experienced yet with Rust, and you try to mix an asynchronous database query
and a web request together in the same event loop, or you wanted to use a
reference to `self` in an inner future (which might suddenly want a static
lifetime), you quite easily end up into trouble... Trouble like a couple of
pages of errors, that are just not readable at all. And you get out maybe by
knowing to use a `map_err` in that one future call after the second `then`, or
by not referencing `self` in your futures...

Now when reading the announcement, and I've read and understood the RFC's, the
next generation of async Rust will help here tremendously. And I will
definitely be amongst the first ones adding the changes to my code, to finally
make it cleaner and nicer for the next developer to jump in.

~~~
harpocrates
You've changed my mind on adding special syntax for `async`, generators, and
results (`?`). I previously thought it was a big mistake given that these all
generalize as monads (granted, there is some ground to be covered before such
an abstraction would fit in Rust).

What I hadn't considered: specialized syntax leads to better error messages
for the most common cases. That's probably quite a good thing, especially
since descriptive error messages make me much more productive. (Not to mention
that specialized syntax also acts as a type annotation of sorts too; a common
problem I have in Haskell is figuring out _which_ monad a certain `do` block
is using.)

~~~
Rusky
> (granted, there is some ground to be covered before such an abstraction
> would fit in Rust)

I would claim that such an abstraction is fundamentally incompatible with
Rust.

Not only does Rust lack the means to write a Monad trait on which to build do-
notation, but even given HKT there's no single type signature that the various
monad instances would fit. `Result` and `Option` are type constructors while
`Iterator` and `Future` are generic traits; some instances require `Fn` or
`FnMut` while others require `FnOnce`.

And even assuming those problems could be solved, the way do-notation
interacts with control flow is not composable with idiomatic Rust. Nested
closures prevent the use of return/break/continue and imperative loops;
Haskell doesn't have those features so people just lift their functional
counterparts into monads. Monad transformer stacks make the situation even
worse- they are a pain to compose even with each other, let alone imperative
code.

If you want a unifying mechanism for this stuff in Rust it's gonna need to be
fundamentally more powerful than monads. Scoped continuations, maybe?
Certainly nothing that looks like >>=.

~~~
akotulski
Algebraic effects are new hotness in FP research. They are easier to compose
than monads and they can express things like async/await naturally. However,
I'm not sure this approach works as intended with imperative programs where
code will have (side) effects sprinkled everywhere. And there is no GC in rust

~~~
Rusky
I'm a fan of effects, and I think they would work great for Rust. (I/O just
probably wouldn't be one of them, or else it would be "on by default" like
`Sized`.)

I'm not sure how they'd give you a unified mechanism to _implement_ these
kinds of things, though. The Monad typeclass lets you implement new instances
in libraries. Is there any work on defining effects like async/await in
libraries? If so I imagine they'd still have to use something like
continuations.

------
zanny
Heres just hoping that Mozilla is prepared to take responsibility for what
they are trying to accomplish in the long haul.

A _lot_ of companies have tried to make products that are both infinitely
backwards compatible and always supported while still introducing breaking
changes like this. It quickly becomes a giant internal mess of trying to
figure out what the most common denominator of feature requirements to
implement new things is. Developers will start making ergonomic decisions in
their changes (well, it could support 2021, but I want a 2024 feature so I'm
going to use it and peg this feature to 2024 minimum) and new changes need to
be tested against _every_ different language iteration.

This might seem like the best answer now, I just hope its not biting off more
than anyone can chew in 2030. C++ had an era of malaise where conflicting
implementations of the standard library across a dozen+ platforms led to the
complete abandonment of it by the mid 2000s and it took Herb Sutter and
friends to bring C++ back from the dead with _one_ unified single truth of C++
with concrete compiler flags and tons of caution before adopting anything new
to make sure all participants were capable of fielding it quickly enough to
avoid the ecosystem fragmentation of the past.

Rust is advantaged today with only one major implementation, but if mrustc or
other alternative Rust compilers become popular mixing those _with_ epochs /
eras / editions can spell disaster for language portability.

Its not an impossible task, but it is definitely a _huge_ one. And its not the
kind of work hobbyists will ever be willing to put up with in the long term,
and its the kind of work that requires extraordinary familiarity with the
whole of rustc, its design process, the RFCs, LLVM, etc. Its its opposite kind
of work to what you put on the easy issues list for new contributors.

It is the primary reason why most software staggers its releases and
depreciated support. Why Microsoft dropped Windows XP at all despite its wide
adoption. Because even with billions of dollars of cash on hand trying to keep
multiple parallel interconnected but distinct code paths functioning while
both securing and improving them in isolation or together is in the highest
echelons of software complexity and difficulty.

~~~
steveklabnik
So, two things:

> Heres just hoping that Mozilla is prepared

Rust is an open source project Mozilla contributes to heavily, it's not a
Mozilla project. This is the Rust project's problem, not Mozilla's problem.

(For example, Mozilla employees, of which I am one, are a minority in
governance these days. We're the largest single group of people by employer,
but are at 50% representation on the core team and are something like between
10%-20% of the rest of the teams, which have just as much jurisdiction over
Rust as the core team does.)

> It quickly becomes a giant internal mess

This is why, as noted elsewhere in the thread, editions can only tweak the
frontend of the compiler. By the time you hit MIR, the main intermediate
representation, all edition differences are gone. This is for both compilers
and humans. As you rightfully say, if we allowed arbitrary changes, it could
significantly increase technical debt. But it'd also be very hard for humans
to understand as well. We won't be fundamentally changing what Rust is for
these reasons.

~~~
lmkg
Is MIR being treated as part of the language definition? Most languages would
treat such a thing as an implementation detail, so defining the constraints in
that fashion seems like it still looks like it may tie you to the reference
implementation.

~~~
apendleton
My maybe-wrong sense was more than the MIR could change from one compiler
release to the next, but that the editions couldn't introduce language changes
that would require any given release of the compiler to have to produce MIR of
a different kind for code of one edition vs. another. You'll be able to
compile a single binary relying on different libraries pinned to different
editions, and I think the idea is that from the MIR stage of the build onward,
whatever differences may exist (e.g., a reserved word in one edition might be
a function name in another) have to be papered over so that whole-program
optimization/compilation can occur.

------
gandreani
Lots of nice language improvements lined up for this year

I haven't played with Rust but I like the ecosystem and transparency.

Something that stands out is the Compatibility across editions section. Seems
like they really thought this through:

> you can be on a different edition from your dependencies.

> Edition-related warnings...must be easily fixable via an automated migration
> tool (rustfix). Only a small minority of crates should require any manual
> work to opt in to a new edition

> the progression of new compiler versions is independent from editions; you
> can migrate at your leisure, and don’t have to worry about ecosystem
> compatibility; These are huge!

This really helps with ecosystem fragmentation. Other languages take note
(please!)

Another thing that stood out was the embedded as first class citizen:

> Embedded devices. Rust has the potential to make programming resource-
> constrained devices much more productive—and fun! We want embedded
> programming to reach first-class status this year.

This seems like the only thing on the list that might not finish in time for
the year or will be sub-par. I don't know how much more work they need to do
but embedded programming requires fine-tune memory management and access to
special registers on a _per-hardware basis_. A lot of times these things fly
in the face of assumptions many programming languages (and compilers) make

~~~
masklinn
Editions sound like an interesting riff on C/C++'s standards thing.

The post isn't really clear what will be gated behind editions though, only
non-BC syntactic changes (e.g. literally just new keywords)?

~~~
steveklabnik
Yeah, this post is intended to be a high-level explanation, so we didn't dig
into the details. I left a comment below about this:
[https://news.ycombinator.com/item?id=16569751](https://news.ycombinator.com/item?id=16569751)

~~~
masklinn
OK so non-BC syntactic changes, and warning -> error transitions. Didn't think
about the second one but that's way cool.

Still, I think it's short and simple enough that it could have been noted in
the section, which I feel currently talks about editions a lot but doesn't say
much about them.

------
swfsql
I'm an average programmer, but I honestly don't get the goal of inclusiveness
[edit: from the Rust 2017 Survey Results]

> Diversity and inclusiveness continue to be vital goals for the Rust project
> at all levels.

I mean.. lifetime checks won't stop working if you don't consider yourself
heterosexual or anything o.O The two matters simply don't mix in my head

~~~
nemothekid
It's less about goals of the technical project, and more about goals of the
organization. Rust the language is written by people, The Rust Team, most of
whom I'd imagine are volunteers. In order to guarantee the life of the
project, its important for potential contributors to not only feel comfortable
using the language and writing code, but also feel comfortable in discussing
the future potential features and use cases for the language.

It is important for projects, now, to state their goals upfront and be clear,
especially when you could have 1000s of contributors from all over the world.
This is something that's new for software projects, but as open source becomes
larger and more diverse its becoming more necessary. The alternative has been
a community based loosely around some invisible set of rules that alienates or
drives away potential contributors or sparks some drama that ends up on the
top of Reddit/HN/etc.

Lifetime checks will stop working if the project gets abandoned over political
issues.

~~~
swfsql
I see, but this is still a political issue. Maybe a lot of minorities people
just voted "no" in that survey question.

Because.. why excluding people based on their skin color is discriminatory,
but including people based on their skin color is not discriminatory?

~~~
awestroke
Discrimination, noun:

> the unjust or prejudicial treatment of different categories of people,
> especially on the grounds of race, age, or sex.

Is it unjust to make sure people from a minority do not feel alienated?

~~~
xedrac
Is it just to alienate the majority to encourage the minority? A lot of
companies promoting "diversity" certainly think so.

~~~
webkike
The rust team isn't alienating anyone

------
Shoothe
> Tooling improvements

For me that's the biggest issue currently with Rust. Type inference via "let"
only makes it harder as I can't really know what type a certain variable or
expression is without carefully tracking docs. I've tried two Rust plug-ins
for VS Code and even though they installed required dependencies I still
couldn't have proper list of members when pressing "dot" and without that I
feel like programming in the 90's.

~~~
fnord77
intellij's rust plugin is pretty good at type interference.

Also sometimes I just let the compiler tell me by forcing the let variable to
something that it is obviously not:

`let not_a_string: String = get_something_that_I_have_no_idea();`

error [4242]: expected type String, found type &*YouWouldNeverHaveGuessed

~~~
w4tson
You can get feedback before the compiler kicks in by asking IntelliJ to
explicitly define the type.

It’s a trick I used quite a bit when playing about with rust, and Kotlin
actually.

Alt + Enter should invoke intentions pop up, you can do it from there. (I
think)

------
AceJohnny2
> _Embedded devices_

I'm excited about this. In my experience, embedded (and by extension, a large
part of kernel/driver programming) is the last stronghold of C, because it's a
place where you really need fine-grained control of your environment and C
gives you that by default.

It's my day-to-day workhorse, and I often feel like I'm stuck in the dark ages
still dealing with issues of tooling and expressiveness that CS has solved
long ago. Free me!

~~~
anderspitman
I love C for it's simplicity, but I'm super excited to see Rust get a foothold
in embedded as well.

------
ch4s3
I like that they are targeting CLI apps[1], it seems like a great fit for Rust
and a nice onramp for the ecosystem for newcomers.

[1] [https://internals.rust-lang.org/t/announcing-the-cli-
working...](https://internals.rust-lang.org/t/announcing-the-cli-working-
group/6872)

------
krylon
Okay, after two failed attempts (mainly due to lack of motivation, I hasten to
admit), I think it's time for me to learn me some Rust.

I spent a long time working mostly with dynamically typed languages, but over
the past few years, I have slowly drifted back into statically typed
territories. At home, I have used Go a lot, at work, I have grown to like C#.
Rust kind of looks like the next logical step along that trajectory, doesn't
it?

And I get the impression that people who took the time to learn Rust enjoyed
it very much. So here's my delayed new-year's resolution (I am the ____ing
king of procrastination!): I am going to learn Rust and I am going to like it
(I hope)!

~~~
kibwen
If you have any questions, feel free to come ask at /r/rust, where we strive
to be moderately less of a shithole than reddit in general. :)

~~~
littlestymaar
The same way a 4 star hotel is «moderately less of a shithole» than a slum ;)

------
steveklabnik
You may have noticed a subtle change: what was previously called “epochs” is
now “editions.”

Lots of great stuff coming this year! As always, happy to answer any
questions.

~~~
cesarb
Could this be used to add an "Ord::clamp" or similar to the stdlib such that
it's invisible (and thus wouldn't cause any conflict) to crates with an older
"edition"?

~~~
Manishearth
I think for such things it's preferable to just have a `clamp` method as a
static method, i.e. you call it with `Ord::clamp(foo, bar)` instead of
`foo.clamp(bar)`.

But yes, it could.

Generally the trend seems to be to still try to avoid having actual breakages
in the editions unless we _have_ to, and this seems like one of those cases
where we don't.

That said, adding Ord::clamp doesn't _technically_ count as a breakage for
Rust, Rust's stability guarantee does not include "we added a method to this
trait/type and now you have to disambiguate via UFCS" or "we added a thing to
this module and now you have to alias your import" because it's not really
possible to have that stability guarantee and continue to evolve the stdlib.

 _That_ said, given that Ord is in the prelude, the bar for adding stuff to
that is much higher. And Rust also cares about the impact of not-technically-
breaking changes like these, so we definitely wouldn't just add it as a
method.

------
Symmetry
As someone who does a lot of firmware I think I really need to explore more of
what Rust brings to the table there. Interrupts are a major source of
concurrency and I'd like to be fearless about those issues.

~~~
quodlibetor
I'm not experienced in this space, but you might be interested in the Real-
Time For the Masses[1] project. The author of that is the lead of the embedded
devices working group.

1: [http://blog.japaric.io/rtfm-v2/](http://blog.japaric.io/rtfm-v2/)

------
_pmf_
Here's my wishlist for embedded: first class hierarchical state machines,
saturated arithmetic, fixed point types. In bare metal scenarios, these are
much larger areas of potential errors than any ownership issues, since often,
any dynamic allocation is restricted to a mailbox/queue primitive while
everything else is statically allocated.

------
kvark
What I'm missing here is why we need to market it as a distinct Rust 2018
release. Do we have breaking changes that require a new epoch/edition? The
"Language improvements" section doesn't clarify that. I just hope there is
substance in this push, a real _technical_ reason for a new release, not a
marketing one.

~~~
aturon
There are changes that require a new edition, particularly around new
keywords.

However, to be clear, editions are _primarily_ a
marketing/communication/project management tool. They give us a way to try to
bring together a number of threads of work into a coherent whole, with a high
level of polish across the board (including docs and tooling), and then to
present that work to the world with a clear story.

It's worth comparing this to the recent Firefox Quantum release, which was
likewise a singled out release on the normal train process that brought
together a number of important changes, marketing/communication, and a high
level of polish.

~~~
kvark
That's what I've been afraid of. When epochs were announced, I thought it is
kinda nice to have backwards compatibility while introducing breaking changes.
It's a good technical concept. Trying to change it's role into
"marketing/communication/project management tool" out of a sudden is what
puzzles me.

> It's worth comparing this to the recent Firefox Quantum release

I don't think it's a fare comparison. Firefox Quantum doesn't involve much of
breaking changes (if you don't consider deprecating the old plugins one, that
is). And the changes are most drastic since early versions of FF. With Rust
though, it's clearly improving every day, I don't see Q3 2018 as any sort of
"quantum leap". At least for as long as it doesn't include the const generics
:)

~~~
aturon
> Trying to change it's role into "marketing/communication/project management
> tool" out of a sudden

FWIW, this was part of the story from the beginning ([https://github.com/rust-
lang/rfcs/pull/2052](https://github.com/rust-lang/rfcs/pull/2052))

> Firefox Quantum doesn't involve much of breaking changes (if you don't
> consider deprecating the old plugins one, that is).

They weren't just deprecated; they stopped working.

> I don't see Q3 2018 as any sort of "quantum leap"

For people following Rust closely, the Rust 2018 release won't be so special.
But most people aren't keeping up with the details of new releases every six
weeks; for them, we have an opportunity to take stock of what's changed over
the last couple of years, explain the impact on idioms and how to transition
code.

Remember that Rust is fairly unique in having a six week release cycle. Most
other languages have a much slower release cycle, where every release is
"major". Editions give us a way to pull together the rapid work we're doing
into a coherent story.

From a management perspective, it's also a very useful way of focusing our
effort as a community, to make sure all the pieces we've been working on are
coming together into a polished whole on a clear timeline.

------
pknopf
Go is making a large push to wasm as well. There is a branch/fork with a near
complete wasm Go compiler.

I'm interested in seeing how Rust and Go will compare in the future of the
web.

Who will win? ;)

~~~
woah
Do they ship a GC with every webpage then or am I misunderstanding how it
works?

~~~
pknopf
Each module has to have it's own GC.

In my experience, it's been easier to integrate two languages that have GC
(JavaScript and Go) than two languages where only one is GC'd (JavaScript and
Rust).

What will the interop with Rust and JavaScript look like? How will pointers be
managed?

~~~
pcwalton
It's not at all easier to interoperate two separate GC'd languages _unless you
have one garbage collector to manage them both_. Web Assembly does not provide
the hooks necessary to integrate GC, and JavaScript does not provide critical
features, such as finalizers, that are necessary to do things like break
cross-language cycles. Absent that support, manual memory management of DOM
objects is necessary, and Rust is going to have a much easier time of that
than Go will.

~~~
voidlogic
For specific needs I have occasionally made my Go struct constructors
(NewFoobar() *Foobar) use malloc ported to Go + mmap to allocate memory and
said structs have a .Close() method (think defer foobar.Close()). It worked
fine... This is a fine solution/compromise, in 95+% of development solutions
you don't want your devs wasting their time managing memory manually, and in
the worse cases they will get it wrong.

------
HumanDrivenDev
Some honest criticism.

I'm not a guru, but I've used a fair bit of F# and modern C++ in a commercial
setting, so a lot of things in rust weren't too surprising. I learned about
the different kinds of strings (they make sense, even if they're poorly
named). I learned the strict borrowing rules. I learned the strict mutability
rules.

But try as I might, I can't bring myself to care about the difference between
the ~190 different types of iterator[0].

I think I should just be able to use a Iterator trait, but I can't get any of
those concrete instances to match up. It very much triggers my "I don't care
reflex" in a way the other stumbling blocks really didn't.

[0] [https://doc.rust-lang.org/core/?search=Iter](https://doc.rust-
lang.org/core/?search=Iter)

~~~
dbaupp
All those iterator types are exactly the same as C++ having
std::vector::iterator, std::vector::const_iterator, std::deque::iterator, ...,
and exist for similar reasons: mostly zero-overhead abstractions. (This is
even more visible in the range proposals for C++.)

Using concrete types for every adaptor means all the steps in a iterator
transformation pipeline are statically known and (importantly) obvious to the
compiler, and thus is highly amenable to inlining/optimisation to get it down
to something close to a plain 'for' loop. If you're willing to forgo that
performance, it's possible to just put everything behind a pointer/virtual
call with a Box<Iterator<Item = ...>>, which ends up more similar to sequences
in F# etc.

It does seem as if the motivation for this design isn't discussed in the
documentation.

------
Ygg2
Looks neat.

Any notes on const generics e.g.`Array[T, N]`?

~~~
kibwen
The tracking issue for const generics is here: [https://github.com/rust-
lang/rust/issues/44580](https://github.com/rust-lang/rust/issues/44580)

~~~
Ygg2
As far I understand the RFC won't allow for `Array[Y, N]` (or `Array<T, N>` in
Rust parlance) note eddyb's comment:

    
    
         Note that all of this should allow impl<T, const N: usize> Trait for [T; N] {...}, 
         but not actually passing a constant expression to a type/function, e.g. ArrayVec<T, 3>.
    

What I'm actually looking is `Array<Y, size_of::<T>>` for support for data
structures that vary depending on size of `T`.

~~~
tatterdemalion
The RFC supports it, eddyb's list of milestones in the compiler just don't get
you all the way there.

------
tiuPapa
Do we get the fearless concurrency part of rust on wasm?

~~~
skybrian
Webassembly (and JavaScript) are single-threaded. The platform has web
workers, but they are more like processes since they mostly don't share data.

There do seem to be some proposals to add threads, though. Also, it's possible
(but hard) to build cooperative multithreading on top of it; apparently Go is
going to do that.

~~~
GolDDranks
Note that there is also single-threaded concurrency, since concurrency is not
parallelism. The upcoming async stuff is going to help with this.

------
hi41
This post is so well written. It must have taken a lot of time to do this
write-up. Is it written by many people or just a single person?

------
nandita95
I absolutely loved rust and it is very easy to use

------
EugeneOZ
Editions - great thing, thank you VERY much! I love this language and people
who work on it!

