Rust and the case for WebAssembly in 2018
Every now and then a technology comes around that fundamentally changes the game
and how things work. Java and the JVM created a world where the idea of portable
code execution was possible, "compile once, run anywhere" (as long as there was
a JVM available). JavaScript changed how the web worked and went from something
to help manipulate how web pages looked based off user interaction, to its
modern incarnation of full applications that run in the browser.
I think we're at that next technology now and it's staring us in the face, but
because it hasn't been used beyond hobbyist level interaction, it's kind of hard
to see why one might use it for their own purposes yet. I'm talking about
WebAssembly ("wasm" for short). It's a big deal. We're talking an Internet unlike any
that's been seen before and it's going to change everything.
What is wasm?
If you haven't heard of it wasm is a binary format to run programs at native
speed in the browser. What? "That's ridiculous" you might say, well here's an example
of it being used for a neural network to generate anime faces.
The code for that isn't written in JavaScript. Now while that may not be your
cup of tea you might be interested in the fact that someone put the
Godot Game Engine into the browser. This is all early days kind of stuff
with wasm, but it highlights some important things: wasm is powerful, wasm is fast enough,
and soon we will be able to run any application on a single platform; the web.
This is a big deal. Just the other day
wasm became supported on every major web browser. It's here now
and it's going to be around for a very long time.
Alright, so why is it a big deal?
- It's a portable binary format supported in something everyone has, a web
browser. It's very much like Java applets many years ago. - It's platform independent. Mac, Linux, Windows, whatever OS it doesn't matter
as long as it has a web browser. - It's an open standard, so no one company owns it (like Oracle does with Java).
- It's fast. While JavaScript is great due to it's ubiquity and working
everywhere on the web, its semantics limits how fast it can be
(that being said, the JIT compiling in browsers these days is usually good enough).
It has the best parts of what made Java applets popular back in the early days of the web
(portability of code) and it has what made JavaScript the king of the Web (an open standard and
browser support), but with all of the native speed of C, C++, and Rust.
What does this mean for Rust?
We're poised to be THE language of choice for wasm. While C/C++ can be used, they
have many things that can push web developers away from using them. Things that Rust
doesn't suffer from, mainly:
- Packaging libraries is a huge pain
- Segfaults/memory unsafety/Undefined Behavior being easier to hit
- Higher level constructs that are easier to reason about (it doesn't preclude
the notion that something like C++ has nice things like iterators, but it
might not make it worth using because it comes packaged with a language that
has all the issues in 2)
Sounds kind of like what we already say to convince people to use Rust who do
systems programming to use Rust. Except, this time our target demographic is different.
It's not systems programmers, it's web developers. Generally speaking here's
what web developers want and need:
- Easy packaging of libraries
- Being able to just download a package and use it
- Being able to call and use those libraries easily with good documentation
- Easy integration into a build system like webpack or browserify
We have most of these:
- With cargo, we have a build system to package up libraries (and one that all
libraries already use) - We also can again use cargo, but we need to integrate with npm somehow which
I'll talk about later - Rustdoc is a wonderful tool and much easier to go through than a man page
- I don't think we're here just yet but I'll cover it later
We have a lot of what web developers want and can easily make the push to make
it a seamless experience for them, rather than making the mistake of letting
C/C++ become the go-to choice again. Rust can and should become the systems
language of the web, much like C/C++ have been for personal computers for decades.
You might have noticed I haven't mentioned programming languages like
Ruby/Python/Java etc. here, that also cover the same things as Rust (and are arguably
easier to learn) right now in terms of making it a good language for wasm. This
is because they're all dependent on a Garbage Collector. If the point of wasm is
to be fast, then having no runtime to worry about is a good thing. GCs add extra
overhead, would have to be shipped with each wasm package, and at that point you
might as well just use JS which is also GC based but is highly optimized for the
web. This is of course subject to change when WebAssembly gets integration with
the GC of the surrounding environment, e.g. the JavaScript engine. However, this
is something that won't happen for about two years give or take.
This leaves us with Rust, C, or C++ as the only real contenders for using wasm
at the moment, meaning it's ripe for first mover advantage when it comes to
tooling, support, and use.
How do we make it the language of choice?
While I've given up trying to convince die-hard C/C++ people to use Rust when
they can (there are arguments not too, i.e. large code bases like Linux) as the
default, what we can do is convince a whole new generation of programmers to use
Rust. Lots of people are learning to code right now, especially for the first
time, and many of them are learning JS as their first language. Undoubtedly as
the years go on and wasm becomes more of a thing, because it will be, they will
come into contact with it and try it out or have to learn it. We want to
position Rust for that critical confluence of events that will occur which is:
- wasm has matured and more people are using it
- Since people are using it they need to learn the languages made to compile to
wasm - They'll learn the easiest one, with the most documentation, and the generally
accepted standard to use.
We need Rust to be point number 3 in the next few years or else we'll have
missed the boat. We're in a special position to do that now and the sooner we
start on this the better.
I'm going to break down the strategy for this into short, medium, and long term
plans that can help position Rust to be a huge player in the next big thing of
computing.
Short Term
There's two important hurdles we need to clear short term and that's tooling and
compiling Rust to wasm. I'll cover compilation first.
Right now we can compile to wasm with a wasm backend target available now in
nightly. However, we don't have linker support so the binary sizes are large and
we have to use wasm-gc to optimize and clean up the program. LLVM has
landed wasm linker support though so we're already on our way there for compilation to wasm.
Future work over the next year would be making sure it works with most if not all of std
if it
doesn't already (threads aren't supported in the wasm standard yet but will be), as well as
optimizations, and making sure it produces wasm files that work.
Next up is getting the tooling working. This includes three major tools:
- The RLS
- webpack
- NPM
Improving the RLS is going to be critical. Many web developers use editors such as VS Code, Atom,
Sublime Text, and others that are more graphical or are an IDE. There are of course vim/emacs users
as well! The RLS being improved benefits all of these platforms, but especially those who use an
IDE and it's features extensively. We also know of people who won't use Rust until there's an IDE
available anyways, so continuing this work is important for both getting the web developer
demographic as well as getting others who wouldn't use Rust without an IDE. Two birds with one
stone! Most of this is already underway, but having a usable stable version in 2018 that we can
continue to improve will be a big boon. As an addendum to that making it easy to integrate the RLS
with other editors should be a snap as well. Making things easier for end users is always a good
thing for adoption, even if it means we need to do a bit of extra maintenance to keep it working.
Big props to the people working on the RLS already. It's important work!
Next up we need to get integration with webpack working and from what I've seen
it's something that's been experimentally added, with a loader already on NPM!
Being able to drop in files and have it Just Work⢠is going to be important. Webpack has become
the cargo for the web in many ways, so being able to just hook in to that build system with no
effort for people developing their own modules is essential. I really think tooling is a huge
driver of adoption. I know I would hate using Rust without rustup or cargo even if I did like the
language.
Lastly, NPM is the next big piece. What if someone writes a whole module in web assembly?
Where should they distribute it? While crates.io is great for other Rust modules it's
not used for storing code used in web development. NPM is where everyone who does web
development gets their modules from. Where am I going with this? Well the good thing about
wasm is that it's platform-agnostic so we could compile a module to wasm and then upload
it to NPM to then be installed alongside other modules used for development. Being
able to do something like cargo upload --npm
would be great. It'll let us use
Rust tooling locally, but still allow us to hook into the wider web development ecosystem.
With webpack and NPM we'll need to work with the projects' maintainers but they also
either use Rust or already want it in their project so I'm sure it'll be easy to get help
with integrating into those systems.
Medium Term
Tooling aside, what's the next big piece of the puzzle further down the road? I think continued
ergonomic improvements like Non Lexical Lifetimes (NLL), more features like Const Generics and
Associated Type Constructors (ATCs) will help fix some of the pain points of Rust and leverage
it as a more powerful language in general.
Further work on documenting code, producing new tutorials, and continuously engaging with the
web development community and what their needs are when it comes to wasm. Some things will be
out of our reach, like influencing what wasm will be further down the line like with DOM
manipulation, but we can continue to improve the backend of rustc as more wasm features become
available, so that web developers can use them sooner.
Also begin developing more examples with Rust and wasm and showing it off to people. We need
to generate buzz, because it doesn't matter how good your stuff is if no one knows about it.
We'll need to start marketing Rust as a viable language for wasm as the more tricky technical
bits of using it are addressed.
Long Term
I'm going to assume we've done the above two sections, but long term I think it's the same
goals of the community now, grow it, make it easy to use and join, and increase participation.
I think the important thing here is that by getting more people to use wasm we'll have a new
generation of systems programmers who will reach for Rust as their first choice. Maybe even
then we can have a full Rust Stack equivalent to MEAN. I'm thinking maybe something like WARD
(WebAssembly, Rocket, Diesel) but hey that's a far off dream. Still, longterm the goals will
help grow Rust, and enable users to do more cool things whether on the web, in embedded dev,
or something else.
Why does any of this matter?
Now you might be looking at this whole article and say to yourself, "Look, I like
Rust, but I don't do web development so why should I care or put effort into
helping out here?" I'm sure we all want to work on Rust in production or at
least want it to succeed, and for that we need more people using it. So why not
get more people to use it everywhere and make it more accessible? If we start
getting more people to use it, they help create more packages and write blog
posts, which gets more people to use it who can contribute in other ways, which
means now companies might start using it in production and so on and so forth.
Language choice is as much social as it is technical as to why things succeed.
While you might use Rust for other use cases, if it becomes a large enough
community, then you still stand to benefit due to having more hands create more
things and work on the compiler. We lose nothing by inviting more people into
the fold and we stand to gain everything by doing so.
Rust 2018 Roadmap
At this point I think it would be good to point out that 2018 is the prime time
candidate for a big push in wasm and one of the main reasons I wanted to write
this article. I think it also coincides with what we've already been working on
already in 2017 as well. The ergonomics initiative can still be brought forward
into 2018 (NLL, ATCs, Incremental Compilation, and other nice things) because
making the language even friendlier and powerful is a good thing that still
benefits everyone, but also will benefit us by getting more web developers on
boarded to Rust. While some things will directly benefit the wasm-only portion,
i.e. code generation/optimization, which will consume limited compiler team
resources, the longterm benefits far outweigh the initial cost.
The other thing that stands to benefit is documentation and how we onboard new
users. We've poured a lot of resources into this over the past two plus years
since 1.0 and it's payed off through improved error messages and more. Doing
that more will be a good thing regardless of use case.
Lastly the things we need to tackle in the short term seem like the biggest
technical things that we should do now to make further work on this easier.
More concretely as goals for 2018 I think Rust should focus on the following:
- Continued building out and optimizing of the new wasm backend for rustc
- Continued work on ergonomics such as NLL and others
- Continued work on RLS and integrating it into other IDEs/Text Editors easily
- Generate more documentation for beginners/improve current documentation
- Work on webpack integration
- Work on NPM integration
I think this is a good goal; one that's ambitious, but would have a huge impact,
that also builds on existing work, rather than throwing everything we have been
working on now away just because a new year has rolled around. It also has the added
benefit of helping everyone still while also advancing Rust as a language! I'd love
to hear if there's other things people would add or take away from this list, but
this is what I think is critically important for Rust's future.
Conclusion
There's a lot to consider going forward but one thing I think is clear, we need
to act now. While we might not be able to manipulate the DOM with Rust and wasm
yet (allowing a pure Rust stack) we still need to position ourselves for that
future. We're short on time and first to market is a huge advantage in becoming
the default choice (how many times have you been told by someone that they would
make the next big social network that'll be different and wanted your help?).
Displacing that is hard and we even see that when talking about Rust to other
C/C++ devs. Once entrenched, even if one wants to use something else, it's hard
to not use those defaults. If we want to secure a position for Rust in the
future, this is it, and the sooner we get to making wasm a first class citizen
in Rust and for web tooling the better off we'll be when wasm stops being
something that a few people are working on and becomes the web.
Thanks to killercup, badboy, steveklabnik, myrrlyn, and
ManishEarth for offering improvements, corrections, and editing.