On August 23 in Portland, I was fortunate enough to attend Rustconf, a conference for Rust developers from around the world. Rust is a newish programming language that focuses on low-level programming, performance, and provides safety benefits.
At Gandi, we’ve been running Rust in production for over 3 years now. Whenever our servers reply to DNS queries, for example, it’s being served using Rust Code.
I attended several talks at Rustconf by core Rust developers, innovators, and those working on improving Rust. A common theme across the talks and the conference as a whole was the importance of the Rust community, and the necessity to make sure that community is a welcoming space for people of all identities, where people are friendly and ready to help.
My personal journey in Rust has been excellent. While the language is certainly not an easy one to learn, since it shifts the usual paradigms a lot, the community that gravitates around it certainly makes up for it. While trying to learn the language, I’ve experienced welcoming IRC channels with tons of experienced people willing to spend time to share knowledge and help solve problems or explain concepts further.
And from what I could tell from speakers and other people I’ve met at rustconf, it’s a shared feeling.
The keynote was delivered by two veterans of the community, Steve Klabnik and Florian Gilcher, both former Ruby developers who have been involved in the community since 2012. They walked us through the history of the Rust language and syntaxes I’ve never seen. But they spent some time going through recent changes happening in the Rust language (edition 2018 syntax) and exciting changes (async/await) still to come.
After a couple of years in the making, Rust finally settled on a stable syntax to describe async behavior. This syntax is important for Rust because the borrow checker did not previously know how to handle those concepts and would get in the way. To work around those limitations, Rust previously required heavier syntaxes, and sometimes locks which made an async-aware program harder to develop in Rust. This is certainly the most exciting change that’s coming for Rust (expected for 1.39, in October according to release schedule).
Steve and Florian, two Rust core developers and observers, shared how they rely on community feedback through working groups, blog posts, and informal discussions. And they described how that feedback is especially helpful for them to decide how to shape the future of the language.
Because the Rust language is still growing, it also faces new challenges, some are legal (crates.io), but most are organizational. They will be scaling up the number of working groups, trying to onboard more people, but also trying new organizational patterns (orbit).
A Rust-embedded working group is coming soon and embedded is certainly a field where I would love to see Rust used more.
I think the overall message of the keynote was to show that the core team cares about quality a lot, does not intend to rush features but requires a lot of feedback to do this job.
The next session I attended was the “Class fixes; or, you become the Rust compiler” by Isobel Redelmeier.
As a developer, there are three kinds of bugs you might introduce: logic errors, runtime errors, and compile-time errors. Isobell shared how to leverage the Rust compiler and the type system to transform the first two class of bugs into the third kind. Those compile-time errors are the most desirable kind of bug because, if present, your program won’t compile, and you would have the chance to catch bugs during development, not later when your program is already deployed, and running in production with sensitive and live data.
One example of runtime errors is the infamous java null pointer exception. This class of bug happens because you would be passing a null-pointer instead of data, and java requires a developer to check for the sanity of input before acting on it. Leveraging a type system and the monadic Option can help a developer declaring intention and rustc will make sure the null is taken care of.
To paraphrase a former colleague of mine: “A compiler will happily take any sequence of instruction, and transform them into machine code. A type system is not helpful to a computer. It is a tool to help a developer to declare intention and have a compiler check intention is kept.” I think Isobell would agree.
Next on the stage was Gargi Sharma for “Syscalls for rustaceans“. Because Rust is a system programming oriented language, Gargi walked us through some bit of operating system history to explain how systems have been split to reduce size and complexity, and how syscalls are used for that purpose.
Whenever a program needs to trigger a syscall, it will setup register, then context-switch into the kernel which will be dispatched by the OS onto the syscall handler. The OS will do its job, then context-switch back to the program.
Gargi walked us through the strace utility and ptrace subsystem, and showed how to leverage that from Rust programs.
We need such a framework because collecting logs is not enough when trying to debug problems in async code. Having a continuous stream of logs with little to no link between them is of no help for a developer to find bugs. We need to collect context and causality, and provide some structure. Tracing is an elegant solution for that.
It is exposed as a drop-in replacement for log crate but also provides span (distributed tracing -like) APIs which allows you to group and contextualize output.
Eliza made a demo of a medium traffic web server and demonstrated how she could leverage the tracing ecosystem to reconfigure log collection live, and add a filter based on request parameters to highlight the problems, and limit noise.
It is a very promising project, I particularly like the fact that it provides a simple log-like interface that makes it easy to deploy, and lets you add context incrementally. It is an elegant solution to a very complex problem. I can’t wait for more developers to embrace that ecosystem (and it’s mostly free from a performance standpoint to do), and I can’t wait for more specialized tracing collectors (Zipkin, flame graph tracing, …) to come around.
Oliver Schneider then shared ongoing work about constant evaluation in Rust. Like many compiled languages, Rust allows developers to built in variables in the binary, like many languages you can generate those values (macros in C) but options are limited.
This is a problem for many languages, it happens to also be an ongoing discussion in the C++ language too.
How do you generate type that allocates heap at compile-time and makes it available to the binary? Which limitations this type has to comply with to be eligible to compile-time generation?
Oliver shared how Rust is trying to push the envelope of what’s possible and what limitations are to be enforced (no unsafe code, enforce soundness, …). The compiler team has some thoughts about adding a trait similar to Send + Sync. This is already available in nighly.
Again, the compiler team is willing to get more types in but they rely on the community to get feedback about which to get first as well as use-cases.
Then we heard Shoumik Palkar speak about weld. Weld is a language, compiler, and runtime for data pipelines. It started from the observation that data-processing pipelines could gain performance by chaining operations instead of going back and forth between CPU and RAM. For example, a simple map reduce job, you may just rewrite the code to scan the data only once and not store the intermediary values from the map function.
So weld started with a compiler in Scala that transforms their language into an IR for the runtime to transform into code-machine (GPU or CPU) and run. Scala and Rust, being both strongly typed language, are particularly effective solutions to transform AST into an optimized IR.
They had issues with hooking scala (being based on the JVM) into their runtime and ended up rewriting the compiler in Rust (All the necessary libraries to hook into LLVM are already provided by the cargo ecosystem).
Shoumik walked us through some of the challenges rewriting scala to Rust. For example, they had to learn to develop without clone (which copies objects in RAM) which was a performance killer for compilation jobs and use `mem::swap` instead.
Next was Isabella Muerte—a C++ veteran with a massive amount of experience in both C++ (she holds the record for most proposal submitted to a single ISO C++ meeting, https://github.com/slurps-mad-rips/papers) and Rust —to share her experience with C++.
She pointed out how similar C++ and Rust were and how they have two different takes on problems.
But what struck me the most was her feedback about communities, how the Rust communities took a stand for inclusion early on and how they worked for a code of conduct. She also made an argument about how the form of organization matters for a project like Rust. C++ is regulated by ISO, which means it is regulated by international laws so everyone may join, but money is always required to get a voice.
The last talk before the keynote I saw was given by Josh Triplett from the lang team. He walked us through the new syntax introduced in the Rust edition-2018 changes but focused on the path resolution algorithm.
Back in 2017, Rust had some inconsistencies regarding the object lookup algorithm. So the lang team worked to come up with a more consistent algorithm. They came up with a very consistent first version but was to break most of the code in place. While the solution looked nice, breaking the current code was not. They talked a lot about this solution, some members published blog posts about it, and they finally settled on a more stable solution, that both fixed the inconsistencies and allowed a smooth transition.
The overall experience took time, and it takes a lot of effort, discussions, and back and forth to find a satisfying solution for everyone. I’m certainly grateful for the lang team for their hard work. The experience as a simple user is great!
The closing keynote was given by Lin Clark. Lin shared her story of being a woman in tech, attesting she was about to leave the Tech industry, because of known inclusivity problems. She’d been curious about Rust, its community and leaders, and she finally joined Mozilla and the wasm team there.
It looks like she’s been thriving there, at least so far, along with the whole wasm team. Wasm is a first-class citizen for Rust, and it makes it a very good platform to play with wasm. Lin walked us through her experiments around wasm, how she’s has been able to build a bridge between a ton of languages (rust, go, PHP, python, … you name it) and wasm back and forth. The result is so impressive that she has been able to write Rust, compile it down to wasm, then interact with it seamlessly in python and PHP unmodified. The extension to wasm that she talked about is a booklet attached to the wasm byte-code that describes the types and entry points to the binary, which allows each language to translate their native types to the wasm equivalent.
This opens up a lot of interesting ideas on how to wire different libraries amongst languages and platforms.
That’s pretty much a wrap on this report of the Rustconf. One more thing I’d like to talk about is that it feels like a ton of speakers were thankful for the community being so inclusive and so welcoming for newcomers. I, most certainly, am because the help I received when I first learned the language was invaluable, but I have to say this is the first time I’ve been to a computer-related conference with so many women and LGBTQ people speaking or attending, and it looks like the Rust community is doing something right here.
Overall, many thanks to everyone involved in organizing, speaking and joining this Rustconf, this has been a blast, and I can’t wait for next year.
Arthur is a system engineer at Gandi based in our San Francisco office. If you have any questions, feel free to reach out on Twitter @baloose.