gdritter repos rust-examples / 90097e7
started revising for Rust 1.0; Ownership section done, started reference section Getty Ritter 8 years ago
4 changed file(s) with 386 addition(s) and 159 deletion(s). Collapse all Expand all
11 % The Rust Programming Language
22 % G.D. Ritter
3 % March 2014
4
5 # WARNING
6
7 The following presentation is out of date, and may not ever be up-to-date
8 again. Proceed with caution!
3 % May 2015
94
105 # The Rust Programming Language
116
5045 data Point = { x, y : Int }
5146
5247 addPoint : Point -> Point -> Point
53 addPoint p1 p2 = { x = p1.x + p2.x, y = p1.y + p2.y }
48 addPoint l r = { x = l.x + r.x, y = l.y + r.y }
5449
5550 main : ()
5651 main = { let a = { x = 1, y = 2 }
9893 point a(1, 2);
9994 point* b = new point(4, 3);
10095 point c = a.add(*b);
101 std::cout << "{ .x = " << c.x;
102 std::cout << ", .y = " << c.y << " }" << std::endl;
96 cout << "{ .x = " << c.x;
97 cout << ", .y = " << c.y << " }" << endl;
10398 delete b;
10499 }
105100 ~~~~
147142
148143 # Systems Programming Languages
149144
150 ## Nimrod
145 ## Nim
151146
152147 ~~~~
153148 type Point = tuple[x: int, y: int]
171166 ## Rust
172167
173168 ~~~~{.rust}
174 struct Point { x: int, y: int }
169 struct Point { x: isize, y: isize }
175170
176171 impl Point {
177172 fn add(self, other: Point) -> Point {
182177
183178 fn main() {
184179 let a = Point { x: 1, y: 2 };
185 let b = ~Point { x: 4, y: 3 };
180 let b = Box::new(Point { x: 4, y: 3 });
186181 println!("{:?}", a.add(*b));
187182 }
188183 ~~~~
189184
190 # Basics of Rust
191
192 # Basics of Rust
185 # What Makes Rust Interesting
193186
194187 > It's like C++ grew up, went to grad school, started dating Haskell, and
195188 > is sharing an office with Erlang...
196189 >
197190 > —Michael Sullivan
198191
199 # Basics of Rust
200
201 ## Recursive Factorial
202
203 ~~~~{.rust}
204 fn fact1(n: int) -> int {
205 if n <= 0 {
206 1
207 } else {
208 n * fact1(n-1)
209 }
210 }
211 ~~~~
212
213 ## Another Recursive Factorial
214
215 ~~~~{.rust}
216 fn fact2(n: int) -> int {
217 match n {
218 0 => { 1 }
219 _ => { n * fact2(n-1) }
220 }
221 }
222 ~~~~
223
224 # Basics of Rust
225
226 ## An Imperative Factorial
227
228 ~~~~{.rust}
229 fn fact3(mut n: int) -> int {
230 let mut res = 1;
231 while (n > 0) {
232 res *= n;
233 n -= 1;
234 }
235 res
236 }
237 ~~~~
238
239 ## One More Imperative Factorial
240
241 ~~~~{.rust}
242 fn fact4(mut n: int) -> int {
243 for i in range(1, n) { n *= i; }
244 return n;
245 }
246 ~~~~
247
248 # Basics of Rust
249
250 ## Tuples
251
252 ~~~~{.rust}
253 {
254 let t: (int, int, int) = (1,2,3);
255 let (a,b,c) = t;
256 let r = match t { (a,b,c) => a + b + c };
257 }
258 ~~~~
259
260 ## Tuple Structs (i.e. named tuples)
261
262 ~~~~{.rust}
263 struct T(bool, int);
264 fn f(t: T) -> int {
265 let T(myBool, myInt) = t;
266 return if myBool { myInt } else { -myInt };
267 }
268 ~~~~
269
270 # Basics of Rust
271
272 ## Structs
273
274 ~~~~{.rust}
275 struct Point { x: f64, y: f64 }
276
277 fn isOrigin1 (p: Point) -> bool {
278 p.x == 0.0 && p.y == 0.0
279 }
280 ~~~~
281
282 ~~~~{.rust}
283 fn isOrigin2 (p: Point) -> bool {
284 match p {
285 Point { x: 0.0, y: 0.0 } => true,
286 _ => false
287 }
288 }
289 ~~~~
290
291 # Basics of Rust
292
293 ## Enums
294
295 ~~~~{.rust}
296 enum Color { Red, Green, Blue }
297
298 enum Shape {
299 Circle(Point, f64),
300 Rectangle(Point, Point),
301 }
302
303 fn area(s: Shape) -> f64 {
304 match s {
305 Circle(_, sz) => f64::consts::pi * sz * sz,
306 Rectangle(p1, p2) => (p2.x - p1.x) * (p2.y - p1.y)
307 }
308 }
309 ~~~~
310
311 # Pointers and Memory
312
313 # Pointers and Memory
192 # What Makes Rust Interesting
193
194 ## Ownership
314195
315196 \begin{center}
316197 \includegraphics[width=.9\textwidth]{imgs/dawkins-owned.png}
317198 \end{center}
318199
200 ## Ownership
201
202 ~~~~{.rust}
203 #[derive(Debug)]
204 struct MyNum { num: i32 }
205
206 fn main() {
207 let x = MyNum { num: 2 };
208 println!("x = {:?}", x);
209 }
210 ~~~~
211
212 # Brief Aside
213 ## Traits
214
215 ~~~~{.rust}
216 trait ToString {
217 fn to_string(&self) -> String;
218 }
219
220 impl ToString for () {
221 fn to_string(&self) -> String {
222 "unit".to_owned()
223 }
224 }
225 ~~~~
226
227 # Brief Aside
228 ## Traits
229
230 ~~~~{.rust}
231 fn print_excitedly<T: ToString>(t: T) {
232 println!("{}!!!", t.to_string());
233 }
234
235 fn main() {
236 print_excitedly( () );
237 }
238 ~~~~
239
240 # Brief Aside from the Brief Aside
241 ## Polymorphism
242
243 ~~~~{.rust}
244 fn make_pair<A, B>(a: A, b: B) -> (A, B) {
245 (a, b)
246 }
247
248 fn not_eq<A: Eq>(left: A, right: A) -> bool {
249 left != right
250 }
251 ~~~~
252
253 # Brief Aside from the Brief Aside
254 ## Polymorphism
255
256 ~~~~{.rust}
257 fn print_eq<A: Eq + ToString>(left: A, right: A) {
258 if left == right {
259 println!("{} and {} are equal",
260 left.to_string(),
261 right.to_string());
262 } else {
263 println!("{} and {} are different",
264 left.to_string(),
265 right.to_string());
266 }
267 }
268 ~~~~
269
270 # Brief Aside
271 ## Traits
272
273 ~~~~{.rust}
274 /* this is /slightly/ different in the stdlib */
275 trait PartialEq<Rhs> {
276 fn eq(&self, other: &Rhs) -> bool;
277 fn ne(&self, other: &Rhs) -> bool;
278 }
279
280 /* no more methods, but more laws */
281 trait Eq: PartialEq<Self> { }
282 ~~~~
283
284 # Brief Aside
285 ## Traits
286
287 ~~~~{.rust}
288 struct MyNum { num: i32 }
289
290 impl PartialEq<MyNum> for MyNum {
291 fn eq(&self, other: &MyNum) -> bool {
292 self.num == other.num
293 }
294 }
295
296 impl Eq for MyNum { }
297 ~~~~
298
299 # Brief Aside
300 ## Traits
301
302 ~~~~{.rust}
303 /* or just this */
304 #[derive(PartialEq,Eq)]
305 struct MyNum { num: i32 }
306 ~~~~
307
308 # What Makes Rust Interesting
309
310 ## Ownership
311
312 ~~~~{.rust}
313 #[derive(Debug)]
314 struct MyNum { num: i32 }
315
316 fn main() {
317 let x = MyNum { num: 2 };
318 let y = x;
319 println!("x = {:?}", x);
320
321 }
322 ~~~~
323
324 # What Makes Rust Interesting
325
326 ## Ownership
327
328 ~~~~{.rust}
329 #[derive(Debug)]
330 struct MyNum { num: i32 }
331
332 fn main() {
333 let x = MyNum { num: 2 };
334 let y = x; /* <- value moves here */
335 println!("x = {:?}", x);
336
337 }
338 ~~~~
339
340 # What Makes Rust Interesting
341
342 ## Ownership
343
344 ~~~~{.rust}
345 #[derive(Debug)]
346 struct MyNum { num: i32 }
347
348 fn main() {
349 let x = MyNum { num: 2 };
350 let y = x;
351 println!("x = {:?}", x);
352 /* so this does not compile */
353 }
354 ~~~~
355
356 # What Makes Rust Interesting
357
358 ## Ownership --- Explicit Cloning
359
360 ~~~~{.rust}
361 #[derive(Debug, Clone)]
362 struct MyNum { num: i32 }
363
364 fn main() {
365 let x = MyNum { num: 2 };
366 let y = x.clone();
367 println!("x = {:?}", x);
368 /* but this does! */
369 }
370 ~~~~
371
372 # What Makes Rust Interesting
373
374 ## Ownership --- Implicit Copying
375
376 ~~~~{.rust}
377 #[derive(Debug, Clone, Copy)]
378 struct MyNum { num: i32 }
379
380 fn main() {
381 let x = MyNum { num: 2 };
382 let y = x;
383 println!("x = {:?}", x);
384 /* as does this! */
385 }
386 ~~~~
387
388 # What Makes Rust Interesting
389
390 ## Ownership --- Destructors
391
392 ~~~~{.rust}
393 #[derive(Debug)]
394 struct MyNum { num: i32 }
395
396 impl Drop for MyNum {
397 fn drop(&mut self) {
398 println!("dropping: {:?}", self)
399 }
400 }
401
402 fn main() {
403 let x = MyNum { num: 2 };
404 println!("x = {:?}", x);
405 }
406 ~~~~
407
408 # What Makes Rust Interesting
409
410 ## Ownership --- Special Clones
411
412 ~~~~{.rust}
413 #[derive(Debug)]
414 struct MyNum { num: i32 }
415
416 impl Clone for MyNum {
417 fn clone(&self) -> Self {
418 println!("Cloning a MyNum...");
419 MyNum { num: self.num }
420 }
421 }
422
423 fn main() {
424 let x = MyNum { num: 2 };
425 let y = x.clone();
426 println!("x = {:?}", y);
427 }
428 ~~~~
429
430 # What Makes Rust Interesting
431
432 ## References
433
434 \begin{center}
435 \includegraphics[width=.9\textwidth]{imgs/dril-owned.png}
436 \end{center}
437
438 # What Makes Rust Interesting
439
440 ## References
441
442 ~~~~{.rust}
443 #[derive(Debug)]
444 struct MyNum { num: i32 }
445
446 fn some_func(_: MyNum) {
447 println!("yeah, whatevs");
448 }
449
450 fn main() {
451 let x = MyNum { num: 2 };
452 some_func(x);
453 println("{:?}", x);
454
455 }
456 ~~~~
457
458 # What Makes Rust Interesting
459
460 ## References
461
462 ~~~~{.rust}
463 #[derive(Debug)]
464 struct MyNum { num: i32 }
465
466 fn some_func(_: MyNum) {
467 println!("yeah, whatevs");
468 }
469
470 fn main() {
471 let x = MyNum { num: 2 };
472 some_func(x);
473 println("{:?}", x);
474 /* ERROR: use of moved value */
475 }
476 ~~~~
477
478 # What Makes Rust Interesting
479
480 ## References
481
482 ~~~~{.rust}
483 #[derive(Debug)]
484 struct MyNum { num: i32 }
485
486 fn some_func(_: MyNum) -> MyNum {
487 println!("yeah, whatevs");
488 }
489
490 fn main() {
491 let x = MyNum { num: 2 };
492 let y = some_func(x.clone());
493 println("{:?}", y);
494 /* works---but so tedious! */
495 }
496 ~~~~
497
498 # What Makes Rust Interesting
499
500 ## References
501
502 ~~~~{.rust}
503 #[derive(Debug,Clone)]
504 struct MyNum { num: i32 }
505
506 fn some_func(_: MyNum) {
507 println!("yeah, whatevs");
508 }
509
510 fn main() {
511 let x = MyNum { num: 2 };
512 some_func(x.clone());
513 println("{:?}", x);
514 /* works---but not what we want */
515 }
516 ~~~~
517
518 # What Makes Rust Interesting
519
520 ## References
521
522 ~~~~{.rust}
523 #[derive(Debug,Clone)]
524 struct MyNum { num: i32 }
525
526 fn some_func(_: &MyNum) {
527 println!("yeah, whatevs");
528 }
529
530 fn main() {
531 let x = MyNum { num: 2 };
532 some_func(&x);
533 println("{:?}", x);
534 /* works! */
535 }
536 ~~~~
537
538 # Pointers and Memory
539
319540 # Pointers and Memory
320541
321542 ## "Owned" Pointers
322543
323544 ~~~~{.rust}
324545 fn main() {
325 let x: ~[int] = ~[1,2,3];
546 let x: Box<[i32]> = Box::new([1,2,3]);
326547 /* x in scope */
327548 {
328 let y: ~[int] = ~[4,5,6];
549 let y: Box<[i32]> = Box::new([4,5,6]);
329550 /* x, y in scope */
330551 }
331552 /* x in scope */
338559
339560 ~~~~{.rust}
340561 fn main() {
341 let x: ~[int] = ~[1,2,3]; // malloc |----+
342 /* ... */ // |
343 { // |
344 let y: ~[int] = ~[4,5,6]; // malloc |-+ |
345 /* ... */ // | |
346 } // free <---+ |
347 /* ... */ // |
348 } // free <------+
562 let x: Box<[i32]> = // malloc |----+
563 Box::new([1,2,3]); // |
564 /* ... */ // |
565 { // |
566 let y: Box<[i32]> = // malloc |-+ |
567 Box::new([4,5,6]); // | |
568 /* ... */ // | |
569 } // free <---+ |
570 /* ... */ // |
571 } // free <------+
349572 ~~~~
350573
351574 # Pointers and Memory
353576 ## "Owned" Pointers
354577
355578 ~~~~{.rust}
356 fn f0() -> ~[int] {
357 return ~[1,2,3]; // returning ownership
358 }
359 fn f1() -> ~[int] {
360 let a = ~[1,2,3];
579 fn f0() -> Box<[i32]> {
580 return Box::new([1,2,3]); // returning ownership
581 }
582 fn f1() -> Box<[int]> {
583 let a = Box::new([1,2,3]);
361584 let b = a;
362585 return a; // error: use of moved value: `a`
363586 }
364 fn f2() -> ~[int] {
365 let a = ~[1,2,3];
587 fn f2() -> Box::new([int]) {
588 let a = Box::new([1,2,3]);
366589 let b = a.clone();
367590 return a; // fine now; `a` and `b` both valid
368591 }
376599 #[deriving(Clone)]
377600 enum List<T> { Cons(T, ~List<T>), Nil }
378601
379 fn f3() -> ~List<int> {
380 let mut a = ~Cons(1, ~Cons(2, ~Nil))
602 fn f3() -> Box<List<int>> {
603 let mut a = Box::new(Cons(1,
604 Box::new(Cons(2, Box::new(Nil)))));
381605 /* a is mutable */
382606 let b = a;
383607 /* can no longer use a, b is immutable */
394618 ~~~~{.rust}
395619 type t8 = (u32,u32,u32,u32,u32,u32,u32,u32);
396620
397 fn eight_nums() -> ~t8 {
398 ~(1,2,3,4,5,6,7,8)
399 }
400
401 fn main() {
402 let t: ~t8 = eight_nums();
621 fn eight_nums() -> Box<t8> {
622 Box::new((1,2,3,4,5,6,7,8))
623 }
624
625 fn main() {
626 let t: Box<t8> = eight_nums();
403627 /* ... */
404628 }
405629 ~~~~
416640 }
417641
418642 fn main() {
419 let t: ~t8 = ~eight_nums();
643 let t: Box<t8> = Box::new(eight_nums());
420644 /* ... */
421645 }
422646 ~~~~
11 DEPS="rust.tex rust.md"
22 redo-ifchange $DEPS
3 xelatex --output-directory build 1>&2 rust.tex
4 mv build/rust.pdf $3
3 DIR=$(mktemp -d)
4 xelatex --output-directory $DIR 1>&2 rust.tex
5 xelatex --output-directory $DIR 1>&2 rust.tex
6 mv $DIR/rust.pdf $3
7 rm -rf $DIR
11 redo-ifchange rust.md
22 pandoc -f markdown -t beamer --standalone --highlight-style haddock \
3 -V theme=Boadilla -V colortheme=beaver --template=my.beamer <rust.md >$3
3 -V theme=Boadilla -V colortheme=beaver <rust.md >$3