Skip to content

Instantly share code, notes, and snippets.

@mchlrhw
Created March 27, 2018 12:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mchlrhw/5d2c297333031c86298b26cf68997e5d to your computer and use it in GitHub Desktop.
Save mchlrhw/5d2c297333031c86298b26cf68997e5d to your computer and use it in GitHub Desktop.
A presentation on the Rust programming language that I gave to some colleagues at Cocoon
<!DOCTYPE html>
<html>
<head>
<title>Rust - Welcome to the Party</title>
<meta charset="utf-8">
<style>
@import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
@import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic);
@import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);
body {
font-family: 'Droid Serif';
}
h1, h2, h3 {
font-family: 'Yanone Kaffeesatz';
font-weight: 400;
margin-bottom: 0;
}
.remark-slide-content h1 { font-size: 3em; }
.remark-slide-content h2 { font-size: 2em; }
.remark-slide-content h3 { font-size: 1.6em; }
.footnote {
position: absolute;
bottom: 3em;
}
li p { line-height: 1.25em; }
.red { color: #fa0000; }
.large { font-size: 2em; }
a, a > code {
color: rgb(249, 38, 114);
text-decoration: none;
}
code {
background: #e7e8e2;
border-radius: 5px;
}
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
.remark-code-line-highlighted { background-color: #373832; }
.pull-left {
float: left;
width: 47%;
}
.pull-right {
float: right;
width: 47%;
}
.pull-right ~ p {
clear: both;
}
#slideshow .slide .content code {
font-size: 0.8em;
}
#slideshow .slide .content pre code {
font-size: 0.9em;
padding: 15px;
}
.inverse {
background: #272822;
color: #777872;
text-shadow: 0 0 20px #333;
}
.inverse h1, .inverse h2 {
color: #f3f3f3;
line-height: 0.8em;
}
/* Slide-specific styling */
#slide-inverse .footnote {
bottom: 12px;
left: 20px;
}
#slide-how .slides {
font-size: 0.9em;
position: absolute;
top: 151px;
right: 140px;
}
#slide-how .slides h3 {
margin-top: 0.2em;
}
#slide-how .slides .first, #slide-how .slides .second {
padding: 1px 20px;
height: 90px;
width: 120px;
-moz-box-shadow: 0 0 10px #777;
-webkit-box-shadow: 0 0 10px #777;
box-shadow: 0 0 10px #777;
}
#slide-how .slides .first {
background: #fff;
position: absolute;
top: 20%;
left: 20%;
z-index: 1;
}
#slide-how .slides .second {
position: relative;
background: #fff;
z-index: 0;
}
/* Two-column layout */
.left-column {
color: #777;
width: 20%;
height: 92%;
float: left;
}
.left-column h2:last-of-type, .left-column h3:last-child {
color: #000;
}
.right-column {
width: 75%;
float: right;
padding-top: 1em;
}
</style>
</head>
<body>
<textarea id="source">
name: inverse
layout: true
class: center, middle, inverse
---
# Rust - Welcome to the Party
(Everyone's invited)
---
# Old Friends
(You should recognise these guys)
---
layout: false
## Old Friends (i)
Rust has functions, and they're first class! 😁
As well as ints, floats, strings, structs, enums, arrays (OK, they're called slices, but whatever)
It's basically C
[example](https://play.rust-lang.org/?gist=36e8bdbdd609d38bc68bb458b1489f59&version=stable)
---
## Old Friends (ii)
Rust has methods! 😲
And control flow: if/else/else if, while, loop
And it has inheritance, kind of (OK, it's not OO as we know it, but it's close enough)
So maybe it's not C; more like (a more streamlined, opinionated) C++
[example](https://play.rust-lang.org/?gist=c9d8b3652d94ab6541afc3f1ced7017c&version=stable)
---
## Old Friends (iii)
Collections: tuples, vectors, maps and sets
Like Python, don't roll your own collection type unless you have to
The stdlib has you covered
[example](https://play.rust-lang.org/?gist=15f814e546decbb16abcb17ad0cad04e&version=stable)
---
## Old Friends (iv)
Iteration
Iterate over collections
`for` loops that don't look like this:
```c
for (int i; i = 0; i++) {
beer_t *beer = beers[i];
drink(beer);
}
```
but instead look like this:
```rust
for beer in beers {
beer.drink();
}
```
(almost Pythonic, right? Need I say more?)
[example](https://play.rust-lang.org/?gist=11f8cbd518537c3e59342c73e694496b&version=stable)
---
## Old Friends (v)
Concurrency
Many paradigms supported including:
- threads
- async (futures, etc.)
- channel-based communication: SPSC, SPMC, MPSC + MPMC (all of which are
either bounded + blocking, bounded + buffered, or unbounded)
- traditional lock-based data structures
- lock-free data structures
- atomics
Most of the concurrency is provided by libraries:
- channels are in the stdlib, but also in crossbeam
- threads are built-in and use OS threads under the hood (1:1), but green threads (N:1) are available through mioco
- rayon provides easy to use and powerful parallelization tools
[example](https://play.rust-lang.org/?gist=d0d3e1dba7c779e7782d5c434810fabf&version=stable)
---
template: inverse
# Acquaintances
(Possibly familiar, but in a new setting, or wearing different jeans)
---
## Acquaintances (i)
Variable bindings
Syntax: `let var_name: <var_type> = ...;` (but types are often inferred)
Can specify mutability of bindings (immutable by default), e.g. `let mut foo = ...;`
[example](https://play.rust-lang.org/?gist=3721adff500a43175f8f8715d89676c4&version=stable)
---
## Acquaintances (ii)
Traits
Implement shared or common behaviour (think of them as interfaces or superclasses)
Driving force behind generics and type conversion (the whole reason iterators work at all)
Can be applied to types outside the current module (even to native types like u8 and friends)
[example](https://play.rust-lang.org/?gist=1afa8bc7cd207e293b6beb7765a0da5c&version=stable)
---
## Acquaintances (iii)
Somewhat functional
Destructuring pattern matching
Very expression oriented with implicit returns (don't forget your semi-colons! (it's actually fine if you do, it won't type check anyway!))
Sum types (remember enums from earlier, well it turns out they're actually sum types 😱)
Fluent-style APIs are quite common: `foo.iter().map().filter().collect()` to your hearts content
Rust also has what Haskell programmers might call monads (in Rust they're called combinators, which is a little friendlier)
Combinators are a sort of cross between a fluent-API and matching
[example](https://play.rust-lang.org/?gist=6433d2e53c3aacd1e315f32fc7ff0187&version=stable)
---
## Acquaintances (iv)
Type checked error handling with `Error`s and `Option`s
Specific enums that wrap data before it can be used:
```rust
enum Error<T, E> {
Ok(T),
Err(E),
}
enum Option<T> {
Some(T),
None,
}
```
They:
- are the source of all of those ugly `unwrap()` calls you may have seen
- are made palatable by macros, match expressions, and combinators
- make you think about all those errors you used to throw up the stack
- prevent nil pointer exceptions
[example](https://play.rust-lang.org/?gist=320c63f46e6c12425fc69de2fec6f8ea&version=stable)
---
## Acquaintances (v)
Macros! (but don't worry, not the C kind)
Allows codegen mainly (to reduce boilerplate) pre-compilation
You will use macros _all the time_ (but that doesn't mean you'll ever have to write one)
We've already seen `println!` and `vec!`, but attribute-style `derive` macros are much more powerful
[example](https://play.rust-lang.org/?gist=0f8922332cde116580aad84a644ff526&version=stable)
---
template: inverse
# Unfamiliar Faces
(Might have met before, but can't remember where, or you never actually talked to them)
---
## Unfamiliar Faces (i)
Ownership 😨
Prevents you from mutating shared references through compile-time checks
Makes you think about how you are sharing memory (even after you switch back to your native tongue)
[example](https://play.rust-lang.org/?gist=341e4d2d631428f5bd0a4b04c4c72545&version=stable)
---
## Unfamiliar Faces (ii)
Lifetimes 😬
Tracks the "liveness" of references to further enforce the concept of ownership
Prevents dangling pointers and use-after-free bugs
If you're having trouble just take ownership (through Copy or Clone)
You will most often run into lifetime issues when working with strings
[example](https://play.rust-lang.org/?gist=9ef012670aeac636d7241f2ef465eb5a&version=stable)
---
## Unfamiliar Faces (iii)
Two types of string: `String` and `str`
String is a struct, str is a slice
Analogous to the difference between `Vec<u8>` and `[u8]`
str (like slices) most often seen as a reference: `&str` (or `&'static str`)
If you want or need ownership of the string use `String`, otherwise use `&str`
Receiving `&str` as function parameter is most flexible
[example](https://play.rust-lang.org/?gist=5d6e96ea60f8a5a6942b8ce4ea39f3e1&version=stable)
---
## Unfamiliar Faces (iv)
Code safety
Safe by default; use `unsafe` to take matters into your own hands
Mainly used for FFI
[formal definition](https://manishearth.github.io/blog/2017/12/24/undefined-vs-unsafe-in-rust/)
---
## Unfamiliar Faces (v)
Fearless concurrency
Leverages ownership, lifetimes and traits (specifically `Send` and `Sync`) to type check concurrency issues
Prevents a whole raft of bugs at compile time
[example](https://play.rust-lang.org/?gist=536ff1fa2cad76ae4b7debf558849f5f&version=stable)
---
template: inverse
# Drinks and Snacks
(Cheers 🍻)
---
## Drinks and Snacks (i)
The compiler is extremely helpful 🙌
Very specific error messages
With highlighted regions and suggestions for fixes
Cargo (the build tool) is also very userfriendly with testing and benchmarking built in
---
## Drinks and Snacks (ii)
Strongly typed isn't a problem due to type inference
Ditto for lifetime elision
Interfaces, generics and derive macros also lessen the hurt
---
## Drinks and Snacks (iii)
There's a genuine feeling of "if it compiles, it's safe"
The Rust ecosystem is getting pretty featureful in terms of libs
The `serde` story is compelling (and there are similar wins in the areas of DBs (`diesel`) and web frameworks (`rocket`)
---
## Drinks and Snacks (iv)
The community is very helpful and inclusive
Very well coordinated with an established RFC process and regular releases
(I have contributed and will have a [feature](https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.and_modify) in stable soon!)
---
template: inverse
# The Hangover
(Pass me the aspirin 🤕)
---
## The Hangover (i)
Syntax
It's the 21st century, did we learn nothing from Python?
What's with all the braces and semi-colons?
Nested types? I thought this was supposed to be an improvement on C++!
Implicit returns, are you crazy?!
All of the above are valid complaints, but really, they're actually awesome (and after enough time with them you'll think so too 😄)
---
## The Hangover (ii)
More verbose sytax leads to longer definitions
A struct definition followed by one or more impl sections? That can get pretty big, pretty fast
The module system is quite user friendly though, so take advantage of namespaces!
---
## The Hangover (iii)
Ownership and lifetimes can be a pain
But the compiler takes the edge off by being so helpful (plus non-lexical lifetimes are coming very soon)
And there are ways around a lot of the problems you'll face:
- abandon performance in favour of lots of copying
- optimise later once you have a working PoC
- choose a different algorithm/architecture (maybe it's you who is wrong)
---
## The Hangover (iv)
The compiler is slow
But you only really feel that pain on large projects (which I've only experienced when hacking on the compiler)
And they're working on improvements all the time (incremental compilation is now stable)
---
template: inverse
## Takeaway
---
## Takeaway
Useful Resources:
- [The Book](https://doc.rust-lang.org/book/second-edition/)
- [Effective Iterators](http://hermanradtke.com/2015/06/22/effectively-using-iterators-in-rust.html)
- [Error Handling](https://facility9.com/2016/03/error-handling-in-rust/)
Community Pages:
- [This Week in Rust](https://this-week-in-rust.org/)
- [Rust Internals](https://internals.rust-lang.org/)
Personal Blogs:
- [Aaron Turon](https://aturon.github.io/)
- [Niko Matsakis](http://smallcultfollowing.com/babysteps/)
- [Manish Goregaokar](https://manishearth.github.io/)
- [Withoutboats](https://boats.gitlab.io/blog/)
- [Steve Klabnik](http://words.steveklabnik.com/)
---
template: inverse
## Closing Time
(Open up the doors and let you out into the world 🎶)
</textarea>
<script src="https://remarkjs.com/downloads/remark-latest.min.js">
</script>
<script>
var slideshow = remark.create();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment