My 3 years in Rust
or the 3-acts drama
Tomasz Drwięga
@tomusdrw
Parity Technologies
Act 0
The Story
2015
Working mostly as a Javascript developer (full stack).
Rather random gigs than full time job.
A lot of time for experimentation.
2015-05-15
Rust 1.0
Let's write a web server and see how good Rust is!
Iron Web Framework
[dependencies]
router = "*"
staticfile = "*"
[dependencies.iron]
version = "*"
[dependencies.logger]
git = "https://github.com/iron/logger.git"
Iron Web Framework
Wildcards? WTF? The deps were uncompatible.
Implementation of first non-trivial route was killed by `'static` and move semantics.
After few hours: "Nah, will do it faster in node.js"
2015-12
Hey! We are starting a new company and will write an Ethereum Client. We want you to join.
2015-12
Hey! We are starting a new company and will write an Ethereum Client. We want you to join.
Cool! I don't really know C++ that well though.
2015-12
Hey! We are starting a new company and will write an Ethereum Client. We want you to join.
Cool! I don't really know C++ that well though.
We plan to do it in Rust!
2015-12
Hey! We are starting a new company and will write an Ethereum Client. We want you to join.
Cool! I don't really know C++ that well though.
We plan to do it in Rust!
Well, I don't know Rust at all then!
2015-12
Hey! We are starting a new company and will write an Ethereum Client. We want you to join.
Cool! I don't really know C++ that well though.
We plan to do it in Rust!
Well, I don't know Rust at all then!
No worries, we neither!
Act 1
The Confrontation
Game of Life
A new project from scratch, almost no deps at all.
Writing Rust is actually pretty fun!
Enums FTW!
enum MyType {
VariantA,
VariantB,
VariantC,
}
But Tomek: C has enums, Java also has them, a lot of langs do - nothing special.
Enums FTW!
enum MyType {
VariantA(u64, String),
VariantB {
value: u64,
other: String,
},
VariantC,
}
Proper algebraic data types (in func-lang lingo)
For normcores: tuples & tagged unions
Pattern Matching!
enum MyType {
VariantA(u64, String),
VariantB {
value: u64,
other: String,
},
VariantC,
}
match x {
MyType::VariantA(a, b) => {
...
},
MyType::VariantB { value, .. } => {
...
},
_ => {},
}
Parity Ethereum
Substrate
Blockchains?
Verify & Execute to obtain the latest state
Blockchains?
Ethereum Virtual Machine
My first task was to write EVM.
A deterministic and very specific kind of interpreter.
Quite similar to GoL.
Concurrency
Second task was to write a transaction queue.
It took me around 1 month, during which the Rust Compiler was teaching me how to write concurrent programs.
Previous experience: sprinkling "synchronized" in Java code.
How does it work in Rust?
use std::{time::Duration as D, thread};
let mut my_var = 5;
thread::spawn(|| {
my_var += 1;
thread::sleep(D::from_millis(1000));
});
loop {
println!("my_var = {}", my_var);
thread::sleep(D::from_millis(500));
}
How does it work in Rust?
use std::{time::Duration as D, thread};
struct State {
counter: u64,
}
let mut state = State { counter: 5 };
thread::spawn(|| {
state.counter += 1;
thread::sleep(D::from_millis(1000));
});
loop {
println!("counter = {}", state.counter);
thread::sleep(D::from_millis(500));
}
How does it work in Rust?
Borrow checker & move semantics gives the compiler magical powers.
Send + Sync
Shared memory might not be the best concurrency model (practical though) and Rust supports other ways too.
What else did I like?
- hygenic macros - "Things that the rust lang team couldn't come up with a syntax for", e.g. try!
- deriving boilerplate code - #[derive(Debug)]
- Documentation & Testing
- crates.io
Act 2
The Progress & The Future(s)
What improved?
- Ecosystem - crates (quantity & quality)
- Serde - We could finally get rid of ALL custom impls (still few bugs though)
- Non-blocking networking - good bye mio!
- Edition 2018 - module system is now really clean
- Proc Macros & Custom Derive - initially thought that macros won't be needed in the future, lol.
- Cross compilation & WASM
What's still missing?
Ecosystem
I want to show my fellow nodejs devs how easy it is to create an asynchronous web server.
Hyper? Iron? Rocket? Actix-web?
What's still missing?
Async/Await
Feels very rushed currently, while I really like the poll model of futures, I think there is still some work needed to clean things up.
What's still missing?
Async/Await
Feels very rushed currently, while I really like the poll model of futures, I think there is still some work needed to clean things up.
Rust 1.39.0 🎉
What's still missing?
impl Trait / trait aliases
Great progress, but still very incomplete.
Missing in traits, as generics, etc.
What's still missing?
#[derive(Clone)]
struct SharedHandle<T> {
handle: Arc<T>,
}
Reported on 2015-07-09 (sic!)
What's still missing?
Lifetime issues
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:8:19
| - temporary value is freed at the end of this statement
| |
8 | let my_iter = v.into_iter().map(|x| x*x).collect::<Vec<_>>().iter();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| creates a temporary which is freed while still in use
9 | for i in my_iter {
| ------- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
What's still missing?
- Concurrent collections in std
- Futures03
- Error message for futures
- Long types in errors (generics)
- Compilation time
- ....
Thank you!
Q&A
Tomasz Drwięga
@tomusdrw
Parity Technologies
My 3 years in Rust
By Tomasz Drwięga
My 3 years in Rust
- 542