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?

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?

 

https://www.arewewebyet.org/ ?

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!)

github.com/mcarton/rust-derivative

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