-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
368 lines (333 loc) · 16.5 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Rust for Justice</title>
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/solarized.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section>
<img src="images/rust.svg" style="float:right;width:80;height:80px;border:0"/>
<h1>Rust for your brain/team/justice.</h1>
<h4>Clint Byrum -- @SpamapS on Freenode IRC and Twitter. <a href="http://fewbar.com/">http://fewbar.com/</a></h4>
<h5>Cloud Software Engineer, GoDaddy</h5>
<h6><i>Words are my own I do not speak for GoDaddy, Mozilla, or the Rust project.</i></h6>
</section>
<section>
<section>Programming Language Rant</section>
<section><h3>Systems Languages</h3><p/>
<ul>
<li>C and pointers were a revolution - Finally a HIGH level language</li>
<li>C++ -- HIGH level in that you need to be HIGH to appreciate it</li>
<li>C# -- Oh clever another horizontal line -- and foreach</li>
<li>C++11 -- Oh yeah we can have foreach too, but we still call it for.</li>
<li>ObjectiveC -- All your user base are belong to iPhone.</li>
</ul>
</section>
<section><h3>Systems Languages</h3><p/>
Every single C descendent puts memory safety on the user.
</section>
<section><h3>Enter Memory Safe Languages</h3>
Java*, Perl, PHP, Python, Ruby, node.js -- All do GC and take memory control away from programmer.<i><h6>*java still has pointers but doesn't do arthmetic on them</h6></i></section>
<section><h3>GC languages can struggle with concurrency</h3>
<ul>
<li>Java VM pauses threads to GC objects.</li>
<li>Python, Ruby, etc. have Global Interpreter Lock when executing Python code</li>
</ul>
</section>
<section><h3>Shiny New Systems Languages</h3><p/>
<ul>
<li>Go - Compiled duck-typed and syntax sugar for concurrency. Runs inside Go runtime with GC to avoid memory management.</li>
<li>Rust - Compiled, strong-typed with generics. Explicit scoped memory management and object lifetimes expressed in language.</li>
</ul>
</section>
<section><h3>Why not Go?</h3><p/>
It's a great language, and easier to learn. But it only goes halfway into systems programming success, where Rust can give you as much control as C, and has the added bonus of Generics
</section>
</section>
<section>
<section>Rust For your Brain</section>
<section>
Explicit Mutability and borrow rules reduce need for unit tests
<aside class="notes">
The compiler can warn you when you've made something mutable that doesn't need to be.
</aside>
</section>
<section>
Strong typing also means not having to unit test as much.
<aside class="notes">
The compiler will error if you have passed the wrong object or tried to call methods /access attributes that don't exist.
</aside>
</section>
<section>
Trait system gives some of the dynamic language flexibility back
<pre><code data-trim>
use std::fmt;
struct Bus {
name: &'static str,
}
struct Train {
line: &'static str,
}
struct Plane {
callsign: &'static str,
}
impl fmt::Display for Bus {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} bus", self.name)
}
}
impl fmt::Display for Train {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} train", self.line)
}
}
impl fmt::Display for Plane {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} flight", self.callsign)
}
}
fn main() {
let b1 = Bus { name: "LAX Flyaway" };
let t1 = Train { line: "Pacific Coastliner"};
let p1 = Plane { callsign: "El Mariachi"};
println!("I took the {} to the {} and then hopped on the {}.", b1, t1, p1);
}
</code></pre>
<aside class="notes">
Works a bit like C++ templates (UGHGGGG) but calling it traits helps you orient your brain toward what it is appropriate for vs. macros or other meta-programming techniques.
</aside>
</section>
<section><h3>No easier in Python</h3>
<pre><code>
class Bus(object):
def __init__(self, name):
self.name = name
def __str__(self):
return "%s bus" % (self.name,)
class Train(object):
def __init__(self, line):
self.line = line
def __str__(self):
return "%s train" % (self.line,)
class Plane(object):
def __init__(self, callsign):
self.callsign = callsign
def __str__(self):
return "%s plane" % (self.callsign,)
b1 = Bus("LAX Flyaway")
t1 = Train("Pacific Coastliner")
p1 = Plane("El Mariachi")
print("I took the {} to the {} and then hopped on the {}.".format(b1, t1, p1))
</code></pre>
</section>
<section>
<h3>"Fearless Concurrency" -- Go ahead and make a thread, we dare you</h3>
<ul>
<li>Explicit mutability makes it easy to find global mutation</li>
<li>Built in Send/Sync traits for objects allow compile time identification of thread safe objects</li>
<li>Deadlock detection is still NP-complete. -- Hooray we get to keep our jobs</li>
</ul>
</section>
<section>
You can opt out of these safeguards when you need to.
<pre><code>
use std::cell::RefCell;
use std::thread;
let result = thread::spawn(move || {
let c = RefCell::new(5);
let m = c.borrow_mut();
let b = c.borrow(); // this causes a panic
}).join();
assert!(result.is_err());
</code></pre>
<aside class="notes">
unsafe is quite common deep within libraries where unit tests are worth the time to write. The key is that safety is the default, so most of the itime you can refactor the code without worrying about breaking things.
</aside>
</section>
<section>
Opt-in to garbage collection when you need flexible data ownership.
<pre><code data-noescape>
use std::rc::Rc;
struct Owner {
name: String,
// ...other fields
}
struct Gadget {
id: i32,
owner: Rc<Owner>,
// ...other fields
}
fn main() {
// Create a reference-counted `Owner`.
let gadget_owner: Rc<Owner> = Rc::new(
Owner {
name: "Gadget Man".to_string(),
}
);
// Create `Gadget`s belonging to `gadget_owner`. Cloning the `Rc<Owner>`
// value gives us a new pointer to the same `Owner` value, incrementing
// the reference count in the process.
let gadget1 = Gadget {
id: 1,
owner: Rc::clone(&gadget_owner),
};
let gadget2 = Gadget {
id: 2,
owner: Rc::clone(&gadget_owner),
};
// Dispose of our local variable `gadget_owner`.
drop(gadget_owner);
// Despite dropping `gadget_owner`, we're still able to print out the name
// of the `Owner` of the `Gadget`s. This is because we've only dropped a
// single `Rc<Owner>`, not the `Owner` it points to. As long as there are
// other `Rc<Owner>` values pointing at the same `Owner`, it will remain
// allocated. The field projection `gadget1.owner.name` works because
// `Rc<Owner>` automatically dereferences to `Owner`.
println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name);
println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name);
// At the end of the function, `gadget1` and `gadget2` are destroyed, and
// with them the last counted references to our `Owner`. Gadget Man now
// gets destroyed as well.
}
</code></pre>
<aside class="notes">
It's incredible to be able to look at any section of code and know for sure if there is reference counted GC going on.
</aside>
</section>
</section>
<section>
<section>Rust For Your Team</section>
<section><h3>For your dev team...</h3>
Programming languages aren't just for computers.<p/>
Having explicit mutability and reference lifetimes helps be clear to humans too.
<pre><code class="python" data-trim>
important = dict() # Will this change? When? What goes in it?
</code></pre>
<pre><code class="rust" data-trim data-noescape>
use std::collections::HashMap;
let mut important: HashMap<String, Widgets> = HashMap::new();
</code></pre>
</section>
<section>
English/Chinese/Spanish/Hindi/etc. are all terrible at representing abstract concepts succinctly and clearly. Say it with code!
</section>
<section><h3>For your ops team...</h3>
Finding bugs at compile time means throwing better stuff over the wall to ops*.<p/>
<pre><code>
Compiling borrowing v0.1.0 (file:///Users/cbyrum/src/SpamapS/presentation/borrowing)
error[E0505]: cannot move out of `pyth` because it is borrowed
--> src/main.rs:20:30
|
20 | users.insert(&pyth.name, pyth);
| --------- ^^^^ move out of `pyth` occurs here
| |
| borrow of `pyth.name` occurs here
error[E0505]: cannot move out of `kant` because it is borrowed
--> src/main.rs:21:30
|
21 | users.insert(&kant.name, kant);
| --------- ^^^^ move out of `kant` occurs here
| |
| borrow of `kant.name` occurs here
error: aborting due to 2 previous errors
error: Could not compile `borrowing`.
To learn more, run the command again with --verbose.
</code></pre>
<aside class="notes">
Using a system level language should usually mean better performance and smaller footprint too.
* Be DevOps. The real DevOps, where Dev and Ops seek to understand eachother.
</aside>
</section>
<section><h3>For your Dev & Ops...</h3>
<ul>
<li>How things get built and deploy matters. Ruby/Perl/Python packaging can be a nightmare.</li>
<li>C/C++ have layers on layers of dependency hell even after existing for 30 years.</li>
</ul>
</section>
<section><h3>New langs, better package/build/deploy stories.</h3>
<ul>
<li>Go has nice tie-ins with git and builds static binaries</li>
<li>Rust's "Cargo" tool is extremely well thought out and well integrated with crates.io for easy code re-use.</li>
</ul>
<a href="https://crates.io">https://crates.io/</a><p/>
<img src="images/cargo.png"/>
</section>
<section><h3>For your Dev & Ops....</h3>
Who is eating up all my RAM?
<img src="images/top.png"/>
</section>
<section><h3>For your Dev & Ops....</h3>
Nodepool? Call nodepool team. Zuul? Call zuul team. Wait.. JAVA?! ALWAYS JAVA
<img src="images/top.png"/>
</section>
<section><h3>For your Dev & Ops....</h3>
Runtimes matter
<img src="images/top.png"/>
<aside class="notes">
Languages like java that have a standard runtime have
knobs for ops. This shifts responsibility over to ops
team for memory management. These knobs are only
moderately effective and the context with which they
should be turned is confusing. A systems language like C
or Rust requires developers to create context-sensitive
knobs like 'innodb_buffer_pool_size', or better yet,
requires them to manage their own memory effectively.
</section>
</section>
<section>
<section>Rust For Justice</section>
<section>Firefox is aimed at freedom and privacy, and its authors, Mozilla.org, invented Rust.
<img src="images/firefox-quantum.jpg" alt="Firefox Quantum" style="border:0">
</section>
<section><h2>This Is <del>Unix</del> Rust, I KNOW THIS</h2>
<ul>
<li>HTML Rendering engine rewritten in Rust -- "Servo"</li>
<li>CSS Rendering engine rewritten in Rust to be parallelized</li>
<li>Released in November -- super legit</li>
</ul>
</section>
<section><h3>Why would they do that?</h3>
<ul>
<li>Firefox's original C++-bound memory model is basically why Google Chrome/Chromium exists.</li>
<li>Rust authors experimented with the idea that less garbage collection and memory tied more concretely to scope would beat the Process memory model in the long run</li>
</ul>
</section>
</section>
<section>
THANK YOU<p/>
Clint Byrum -- @SpamapS on Freenode IRC and Twitter. <a href="http://fewbar.com/">http://fewbar.com/</a>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
dependencies: [
{ src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
</body>
</html>