# Rust
“GC ? Where we're going, we don't need GC.”
Doc Emmett Brown
Mathieu Poumeyrol @kalizoy
Pierre Baillet @octplane
--
## Who are we ?
- Mathieu Poumeyrol, backend
- Pierre Baillet, devops
- Ex-fotopedia
- Ex-IDM
- classmate in school
Note:
https://www.google.fr/search?q=coll%C3%A8gues&espv=2&biw=1745&bih=1005&source=lnms&tbm=isch&sa=X&ei=bK8GVc7WLoqsU8vtgMAH&ved=0CAYQ_AUoAQ#tbm=isch&q=cat+dog+friendship ou autre chose ?
--
## Outline
- Rust, another language ?
- Rust in the languages landscape
- Rust in action
- Rust and its ecosystem
---
## Rust, another language ?
Note:
- Looking for a C++ replacement
- Industry backed and Open-source
- I love it when a plan comes together
--
### Looking for a C++ replacement
- Used in various part of the industry: performance, embedded, portable
- Numerous recent improvements: lambda closure, local type inference
But !
- C++ is now 32 years old: older than most of you
- Complex language with very tricky resource management issues
- Very difficult to learn when coming from a "modern world": java, ruby, python, even perl
Note:
Il fait peur ce slide (bouh!)
--
### Industry backed and Open-source
- Created by Graydon Hoare in 2009, then sponsored by Mozilla
- Fully Open-source, MIT License
- Backed by the Mozilla Foundation, known for its openness
Note:
Par opposition aux langages à BDFL (benevolent dictator for life) comme
python, ruby, perl et aux languages enterprise-backed mais "fermés ou presque" : Go, Java.
--
### I love it when a plan comes together
- LLVM allowed huge progress in language compilation
- Scala showed that hybrid functional languages were Business ready
- Now was the right time to create a more modern language
Note:
Le titre est un clin d'oeil a l'agence tout risque.
LLVM et sa conception modulaire ont encouragés le développement
de compilateurs basés sur le même socle. Scala et son approche functionnelle ont montré
à l'industrie qu'il était possible de construire du code dans ces langages plus fonctionnels
tout en étant business (par opposition a universitaire pour Haskell et ses cousins).
Now was: Le bon moment pour faire cela était il y a 2 ans, et ça a été fait par Mozilla. Sans troller,
on peut quand meme souligner que Go n'est pas fondamentalement plus moderne comme langage.
---
## Rust in the language landscape
Note:
- Target Environments
- Traditional Features
- Functional Features
- Ownership and lifetime management
--
### Target Environments
- Rust generates machine code, like C, C++, or Go.
- Rust references are translated to plain pointers.
- Cross-platform implementations.
From kernel drivers to datacenter-wide distribution...
--
### Traditional Features
- imperative programming
- functions, return types
- loops, iterators, arrays
- object-oriented: traits, generics
- packages, dependencies
- base types for string, numbers,...
- concurrency
- stdlib
--
### Functional Features
- closures
- immutability
- local type inference
- pattern matching
- procedural macros
--
### Ownership and lifetime management
--
### Ownership and lifetime management
#### Raw pointers : what could go wrong ?
- overrun and underrun
- access to freed memory
- access to invalid memory
- use of unitialized value
- missing free
- double free
- malloc/free VS new/delete
- ...
--
#### Strategies for Resource Management
Technique | Environment |
Malloc and free | Standard libc |
Smart pointer support | Standard libc++ |
ARC | Apple Objective-C |
Garbage Collector | JVM, Go, Ruby, ... |
Borrow Checking | Rust |
--
#### Rust compromise
- ask the developper to go halfway
- make sure the compiler do the rest
- generate code as efficient as C
---
## Rust in action
Note:
- Hello world
- Traditional features
- Functional features
- Safety features
--
### Hello world
```rust
fn main() {
println!("Hi future rustaceans!");
}
```
```rust
Hi future rustaceans!
```
--
### Structs are concrete objects
use std::num::Float;
struct Point {
x:f64, y:f64
}
fn main() {
let a = Point { x:3.0, y:4.0 };
let dist = (a.x*a.x + a.y*a.y).sqrt();
println!("{} {} {}", a.x, a.y, dist);
}
3 4 5
--
### Structs have methods
```rust
use std::f64::consts::PI;
use std::num::Float;
struct Circle { x:f64, y:f64, radius:f64 }
impl Circle {
fn area(&self) -> f64 { PI*self.radius*self.radius }
}
fn main() {
let c = Circle { x:3.0, y:3.0, radius:2.0 };
println!("{:?}", c.area());
}
```
```rust
12.566371
```
--
### Traits for abstraction
trait HasArea { fn area(&self) -> f64; }
struct Circle { x:f64, y:f64, radius:f64 }
impl HasArea for Circle {
fn area(&self) -> f64 { PI*self.radius*self.radius }
}
struct Rect { x1:f64, y1:f64, x2:f64, y2:f64 }
impl HasArea for Rect {
fn area(&self) -> f64 { (self.x2-self.x1).abs()*(self.y2-self.y1).abs() }
}
fn main() {
let r = Rect { x1:3.0, y1:3.0, x2:10.0, y2: 7.0};
let c = Circle { x:3.0, y:3.0, radius:2.0 };
println!("{:?} {:?}", r.area(), c.area());
}
28 12.566371
--
## Functional features
--
### Abstract collections, closures
fn main() {
let r = Rect { x1:3.0, y1:3.0, x2:10.0, y2: 7.0};
let c = Circle { x:3.0, y:3.0, radius:2.0 };
let shapes:Vec<&HasArea> = vec!(&r, &c);
let areas:Vec<String> =
shapes.iter().map(|s| s.area().to_string()).collect();
println!("{}", areas.connect(" "));
}
28 12.566371
--
### Enumeration and pattern matching
enum Shape {
Circle { x:f64, y:f64, radius:f64 },
Rect { x1:f64, y1:f64, x2:f64, y2:f64 },
}
impl HasArea for Shape {
fn area(&self) -> f64 {
match self {
&Shape::Circle { radius:r, .. } => PI*r*r,
&Shape::Rect { x1:x1, x2:x2, y1:y1, y2:y2 } =>
(x2-x1).abs()*(y2-y1).abs()
}
}
}
28 12.566371
--
### Safety features - Ownership
{
int \*x = malloc(sizeof(int));
*x = 5;
free(x);
|
{
let x = Box::new(5);
}
|
Note:
- Box is the heap allocator
- pattern works for any kind of resource
--
### Safety features - Ownership rule
Each allocated resource is owned by a unique owning handle.
When the handle goes out of scope, the resource is destroyed.
--
### Safety features - Transferring ownership
fn add_one(mut num: Box<i32>) {
*num += 1;
}
fn main() {
let x = Box::new(5);
add_one(x);
println!("{}", x);
}
error: use of moved value: `x`
Note:
Ownership has been transferred to add_one, x is dead in main.
--
### Safety features - Transferring ownership fixed
fn add_one(mut num: Box<i32>) -> Box<i32> {
*num += 1;
num
}
fn main() {
let x = Box::new(5);
let y = add_one(x);
println!("{}", y);
}
6
Note:
Ownership is transferred back to main through return value.
--
### Safety features - Borrowing
Rust allow the owner of a handle to lend out:
- exactly one mutable reference
- one or more immutable references
--
### Safety features - Borrowing
fn add_one(mut num: &Box<i32>) {
*num += 1;
}
fn main() {
let x = Box::new(5);
add_one(&mut x);
println!("{}", x);
}
6
Note:
Ownership of the box stays to the variable x.
Only a mutable reference is lend to add_one.
--
## What's new here ?
- Ownership and borrowing are not new patterns...
- but now they are enforced by the compiler.
--
## Safer API design
- No exception (but a handful of method can "panic")
- Pervasive use of `Option<>` and `Result<>`
--
## `Option<>` example
```rust
fn main() {
fn compute(x: Option) -> String {
match x {
Some(a) => format!("The value is: {}", a),
None => format!("No value")
}
}
println!("{}", compute(Some(42))); // The value is: 42
println!("{}", compute(None)); // No value
}
```
--
## `Result<>` example
```rust
fn parse_version(header: &[u8]) -> Result {
...
}
let version = parse_version(&[1, 2, 3, 4]);
match version {
Ok(v) => {
println!("working with version: {}", v);
}
Err(e) => {
println!("error parsing header: {}", e);
}
}
```
---
## Rust and its ecosystem
Note:
- Release plan
- Practical experience
- Cross-platform, cross-paradigm, cross-industry
--
### Release plan
- Rust 1.0-alpha2 – Feb 20
- All 1.0 modules stable on nightly – around Mar 9
- Rust 1.0-beta – Mar 31
- Rust 1.0 – May 15
--
### Release plan — What's in 1.0 ?
- after years of fumbling, the language now "feels" right
- but a lot of efforts in reducing the 1.0-commited surface
- no procedural macros (aka compiler plugin)
- minimal collection footprint (no "Map" or "List" trait)
- and big features just left for later
- async io
- higher kind types
- opt-in GC
--
### Practical experience — How does Rust feel ?
- big language
- young language
- new concepts
- unforgiving compiler
--
### Practical experience — How fast is it ?
- busy beaver: in the ballpark of C (3 times faster than go and java)
- rumblebars: 3 or 4 times faster than java
--
### Cross-platform
- arduino: pending work on LLVM-AVR
- small ARM boards: odroid and rpi raspbian bootstrapping
- mesos bindings
--
### Cross-industry — Server side
- *hyper*: the de facto standard client and server HTTP library
- *Iron*: web service framework
- *nickel.rs*: kind of the same, with mustache view
- *conduit*: not sure what it is...
- *rumblebars*: handlebars evaluation library
- *rust-serialize* offers JSON ser/deser
--
### Cross-industry — Client side
- *servo*: web rendering engine
- GLFW bindings
- *piston*: A user friendly game engine written in Rust
- kiss3d: Keep It Simple, Stupid 3d graphics engine for Rust
---
### Conclusion
- real-life micro-project: the deployer.
- language almost ready for prime time
- try it, it's free !
--
# Questions ?
## and thank you !