gdritter repos rust-examples / c68e3fe
deleted older slide material Getty Ritter 8 years ago
1 changed file(s) with 0 addition(s) and 814 deletion(s). Collapse all Expand all
534534 /* works! */
535535 }
536536 ~~~~
537
538 # Pointers and Memory
539
540 # Pointers and Memory
541
542 ## "Owned" Pointers
543
544 ~~~~{.rust}
545 fn main() {
546 let x: Box<[i32]> = Box::new([1,2,3]);
547 /* x in scope */
548 {
549 let y: Box<[i32]> = Box::new([4,5,6]);
550 /* x, y in scope */
551 }
552 /* x in scope */
553 }
554 ~~~~
555
556 # Pointers and Memory
557
558 ## "Owned" Pointers
559
560 ~~~~{.rust}
561 fn main() {
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 <------+
572 ~~~~
573
574 # Pointers and Memory
575
576 ## "Owned" Pointers
577
578 ~~~~{.rust}
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]);
584 let b = a;
585 return a; // error: use of moved value: `a`
586 }
587 fn f2() -> Box::new([int]) {
588 let a = Box::new([1,2,3]);
589 let b = a.clone();
590 return a; // fine now; `a` and `b` both valid
591 }
592 ~~~~
593
594 # Pointers and Memory
595
596 ## "Owned" Pointers
597
598 ~~~~{.rust}
599 #[deriving(Clone)]
600 enum List<T> { Cons(T, ~List<T>), Nil }
601
602 fn f3() -> Box<List<int>> {
603 let mut a = Box::new(Cons(1,
604 Box::new(Cons(2, Box::new(Nil)))));
605 /* a is mutable */
606 let b = a;
607 /* can no longer use a, b is immutable */
608 let mut c = b.clone();
609 /* can use both b and c */
610 return b;
611 }
612 ~~~~
613
614 # Pointers and Memory
615
616 ## Dispreferred Style
617
618 ~~~~{.rust}
619 type t8 = (u32,u32,u32,u32,u32,u32,u32,u32);
620
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();
627 /* ... */
628 }
629 ~~~~
630
631 # Pointers and Memory
632
633 ## Preferred Style
634
635 ~~~~{.rust}
636 type t8 = (u32,u32,u32,u32,u32,u32,u32,u32);
637
638 fn eight_nums() -> t8 {
639 (1,2,3,4,5,6,7,8)
640 }
641
642 fn main() {
643 let t: Box<t8> = Box::new(eight_nums());
644 /* ... */
645 }
646 ~~~~
647
648 # Pointers and Memory
649
650 ## References
651
652 ~~~~{.rust}
653 {
654 let p = Point { x: 1.2, y: 3.4 };
655 let q = & p;
656 // both p and q usable
657 }
658 {
659 let q = & Point { x: 1.2, y: 3.4 };
660 }
661 {
662 let p = Point { x: 1.2, y: 3.4 };
663 let r = & p.x;
664 }
665 ~~~~
666
667 # Pointers and Memory
668
669 ## References
670
671 ~~~~{.rust}
672 fn eq(xl: ~List<int>, yl: ~List<int>) -> bool {
673 /* elided */
674 }
675
676 fn main() {
677 let l1 = ~Cons(1, ~Cons (2, ~Nil));
678 let l2 = ~Cons(3, ~Cons (4, ~Nil));
679 println!("{}", eq(l1, l2));
680 println!("{:?}", l1);
681 }
682 ~~~~
683
684 # Pointers and Memory
685
686 ## References
687
688 ~~~~{.rust}
689 fn eq(xl: ~List<int>, yl: ~List<int>) -> bool {
690 /* elided */
691 }
692
693 fn main() {
694 let l1 = ~Cons(1, ~Cons (2, ~Nil));
695 let l2 = ~Cons(3, ~Cons (4, ~Nil));
696 println!("{}", eq(l1, l2)); // ownership of l1 and l2
697 // moves to eq function
698 println!("{:?}", l1); // error: use of moved value!
699 }
700 ~~~~
701
702 # Pointers and Memory
703
704 ## References
705
706 ~~~~{.rust}
707 fn eq(xl: ~List<int>, yl: ~List<int>) -> bool {
708 /* elided */
709 }
710
711 fn main() {
712 let l1 = ~Cons(1, ~Cons (2, ~Nil));
713 let l2 = ~Cons(3, ~Cons (4, ~Nil));
714 println!("{}", eq(l1.clone(), l2.clone()));
715 println!("{:?}", l1);
716 }
717 ~~~~
718
719 # Pointers and Memory
720
721 ## References
722
723 ~~~~{.rust}
724 fn eq(xl: &List<int>, yl: &List<int>) -> bool {
725 /* elided */
726 }
727
728 fn main() {
729 let l1 = ~Cons(1, ~Cons (2, ~Nil));
730 let l2 = ~Cons(3, ~Cons (4, ~Nil));
731 println!("{}", eq(l1, l2));
732 println!("{:?}", l1);
733 }
734 ~~~~
735
736 # Pointers and Memory
737
738 ## References
739
740 ~~~~{.rust}
741 fn eq(xl: &List<int>, yl: &List<int>) -> bool {
742 match (xl, yl) {
743 (&Nil, &Nil) => true,
744 (&Cons(x, ~ref xs), &Cons(y, ~ref ys))
745 if x == y => eq(xs, ys),
746 (_, _) => false
747 }
748 }
749 ~~~~
750
751 # Pointers and Memory
752
753 ## References
754
755 ~~~~{.rust}
756 fn eq<T: Eq>(xl: &List<T>, yl: &List<T>) -> bool {
757 match (xl, yl) {
758 (&Nil, &Nil) => true,
759 (&Cons(x, ~ref xs), &Cons(y, ~ref ys))
760 if x == y => eq(xs, ys),
761 (_, _) => false
762 }
763 }
764 ~~~~
765
766 # Pointers and Memory
767
768 ## References and Lifetimes
769
770 ~~~~{.rust}
771 {
772 let a = ~5;
773 let mut p = &a;
774 {
775 let b = ~8;
776 p = &b;
777 }
778 println!("{}", **p)
779 }
780 ~~~~
781
782
783 # Pointers and Memory
784
785 ## References and Lifetimes
786
787 ~~~~{.rust}
788 {
789 let a = ~5; // malloc |---+
790 let mut p = &a; // |
791 { // |
792 let b = ~8; // malloc |-+ |
793 p = &b; // | |
794 } // free <---+ |
795 println!("{}", **p) // |
796 } // free <-----+
797 ~~~~
798
799
800 # Pointers and Memory
801
802 ## References and Lifetimes
803
804 ~~~~{.rust}
805 {
806 let a = ~5;
807 let mut p = &a;
808 {
809 let b = ~8;
810 p = &b; // error: borrowed value does
811 // not live long enough
812 }
813 println!("{}", **p)
814 }
815 ~~~~
816 # Pointers and Memory
817
818 ## References, Pointers, Mutability
819
820 ~~~~{.rust}
821 {
822 let mut x = ~5;
823 *x = *x + 1;
824 {
825 let y = &x;
826 /* x is not mutable for the rest of this block */
827 }
828 /* x regains mutability */
829 }
830 ~~~~
831
832 # Pointers and Memory
833
834 ## References, Pointers, Mutability
835
836 ~~~~{.rust}
837 enum IntList {
838 Cons { head: int, tail: ~IntList },
839 Nil,
840 }
841 {
842 let mut lst = ~Cons { head: 5, tail: ~Nil };
843 {
844 let y = &(lst.head); // or &((*lst).head)
845 lst = ~Nil;
846 println!("{}", y);
847 }
848 }
849 ~~~~
850
851 # Pointers and Memory
852
853 ## References, Pointers, Mutability
854
855 ~~~~{.rust}
856 enum IntList {
857 Cons { head: int, tail: ~IntList },
858 Nil,
859 }
860 {
861 let mut lst = ~Cons { head: 5, tail: ~Nil };
862 {
863 let y = &(lst.head);
864 lst = ~Nil;
865 println!("{}", y); // BAD
866 }
867 }
868 ~~~~
869
870 # Pointers and Memory
871
872 ## Named Lifetimes
873
874 ~~~~{.rust}
875 fn tail<T>(lst: &List<T>) -> &List<T> {
876 match *lst {
877 Nil => &Nil,
878 Cons(_, ~ref xs) => xs
879 }
880 }
881 ~~~~
882
883 # Pointers and Memory
884
885 ## Named Lifetimes
886
887 ~~~~{.rust}
888 fn tail<'s, T>(lst: &'s List<T>) -> &'s List<T> {
889 match *lst {
890 Nil => &Nil,
891 Cons(_, ~ref xs) => xs
892 }
893 }
894 ~~~~
895
896 # Pointers and Memory
897
898 ## Reference Counting
899
900 ~~~~{.rust}
901 use std::rc::Rc;
902 {
903 let x = Rc::new([1,2,3]);
904 let y = x.clone(); // two references, one vector
905 assert!(x.ptr_eq(y));
906 assert!(*y.borrow() == [1,2,3]);
907 }
908 ~~~~
909
910 ## Garbage Collection
911
912 ~~~~{.rust}
913 use std::gc::Gc;
914 {
915 let x = Gc::new([1,2,3]);
916 // etc.
917 }
918 ~~~~
919
920 # Pointers and Memory
921
922 ## C Pointers
923
924 ~~~~{.rust}
925 use std::ptr::RawPtr;
926
927 #[link(name="foo")]
928 extern {
929 fn unsafe_get() -> *int;
930 }
931
932 fn safe_get() -> Option<int> {
933 unsafe {
934 let i = unsafe_get();
935 i.to_option()
936 }
937 }
938 ~~~~
939
940 # Closures
941
942 # Closures
943
944 > [...] Lambdas are relegated to relative obscurity until Java makes them
945 > popular by not having them.
946 >
947 > —James Iry, "A Brief, Incomplete, and Mostly Wrong History of Programming
948 > Languages"
949
950 # Closures
951
952 ## Functions
953
954 ~~~~{.rust}
955 fn main() {
956 let x = 5;
957 fn inner(y: int) -> int {
958 return x + y;
959 }
960 println!("{}", inner(1));
961 }
962 ~~~~
963
964 # Closures
965
966 ## Functions Do NOT Close Over Env
967
968 ~~~~{.rust}
969 fn main() {
970 let x = 5;
971 fn inner(y: int) -> int {
972 return x + y; // error: can't capture dynamic env
973 }
974 println!("{}", inner(1));
975 }
976 ~~~~
977
978 # Closures
979
980 ## Stack Closure
981
982 ~~~~{.rust}
983 fn main() {
984 let x = 5;
985 let inner = |y| x + y;
986 println!("{}", inner(1));
987 }
988 ~~~~
989
990 ## Stack Closure with Type Annotations
991
992 ~~~~{.rust}
993 fn main() {
994 let x = 5;
995 let inner = |y: int| -> int { x + y };
996 println!("{}", inner(1));
997 }
998 ~~~~
999
1000 # Closures
1001
1002 ## Stack Closures
1003
1004 ~~~~{.rust}
1005 fn my_map<A,B>(f: |&A|->B, l: &List<A>) -> List<B> {
1006 match *l {
1007 Nil => Nil,
1008 Cons(ref x, ~ref xs) =>
1009 Cons(f(x)), ~my_map(f, xs))
1010 }
1011 }
1012
1013 fn main() {
1014 fn incr(x: &int) -> int { x + 1 }
1015 let l = ~Cons(1, ~Cons(2, ~Cons(3, ~Nil)));
1016 println!("{:?}", my_map(|x| x + 1, l));
1017 println!("{:?}", my_map(incr, l));
1018 }
1019 ~~~~
1020
1021 # Closures
1022
1023 ## Owned Closures
1024
1025 ~~~~{.rust}
1026 use std::task::spawn;
1027
1028 fn main() {
1029 let x = ~5;
1030 spawn(proc() {
1031 println!("{}", x);
1032 });
1033 // x is now owned by the proc above
1034 }
1035 ~~~~
1036
1037 # Methods
1038
1039 ## Methods on a Struct
1040
1041 ~~~~{.rust}
1042 use std::f64::{sqrt,pow};
1043 struct Point { x: f64, y: f64 }
1044 impl Point {
1045 fn magnitude(&self) -> f64 {
1046 sqrt(pow(self.x,2.0)+pow(self.y,2.0))
1047 }
1048 fn new((my_x, my_y): (f64, f64)) -> Point {
1049 Point { x: my_x, y: my_y }
1050 }
1051 }
1052 fn main() {
1053 let p = Point::new((2.0,4.0));
1054 println!("{}", p.magnitude());
1055 }
1056 ~~~~
1057
1058 # Methods
1059
1060 ## Methods on an Enum
1061
1062 ~~~~{.rust}
1063 impl<T> List<T> {
1064 fn is_empty(&self) -> bool {
1065 match self {
1066 &Nil => true,
1067 &Cons(_, _) => false,
1068 }
1069 }
1070 }
1071 ~~~~
1072
1073 # Traits
1074
1075 ## Head of a List By Reference
1076 ~~~~{.rust}
1077 fn head<'a, T>(lst: &'a List<T>) -> Option<&'a T> {
1078 match lst {
1079 &Nil => None,
1080 &Cons(ref hd, _) => Some(hd)
1081 }
1082 }
1083 ~~~~
1084
1085 # Traits
1086
1087 ## Head of a List By Value
1088 ~~~~{.rust}
1089 fn head<T>(lst: &List<T>) -> Option<T> {
1090 match lst {
1091 &Nil => None,
1092 &Cons(ref hd, _) => Some(*hd)
1093 }
1094 }
1095 ~~~~
1096
1097 # Traits
1098
1099 ## Head of a List By Value
1100 ~~~~{.rust}
1101 fn head<T>(lst: &List<T>) -> Option<T> {
1102 match lst {
1103 &Nil => None,
1104 &Cons(ref hd, _) => Some(*hd)
1105 // cannot move out of dereference of & pointer
1106 }
1107 }
1108 ~~~~
1109
1110 # Traits
1111
1112 ## Head of a List By Value
1113 ~~~~{.rust}
1114 fn head<T: Clone>(lst: &List<T>) -> Option<T> {
1115 match lst {
1116 &Nil => None,
1117 &Cons(ref hd, _) => Some(hd.clone())
1118 }
1119 }
1120 ~~~~
1121
1122 # Traits
1123
1124 ## Declaring Traits
1125 ~~~~{.rust}
1126 trait Printable {
1127 fn print(&self);
1128 }
1129
1130 impl Printable for int {
1131 fn print(&self) { println!("{}", *self) }
1132 }
1133
1134 impl Printable for bool {
1135 fn print(&self) { println!("{}", *self) }
1136 }
1137
1138 fn main() {
1139 5.print(); true.print();
1140 }
1141 ~~~~
1142
1143 # Traits
1144
1145 ## Using Multiple Traits
1146
1147 ~~~~{.rust}
1148 fn print_head<T: Clone+Printable>(lst: &List<T>) {
1149 match lst {
1150 &Nil => { println!("Nothing!") }
1151 &Cons(ref hd, _) => { hd.clone().print() }
1152 }
1153 }
1154 ~~~~
1155
1156 # Traits
1157
1158 ## Static Dispatch
1159
1160 ~~~~{.rust}
1161 fn printAll<T: Printable>(vec: &[T]) {
1162 for p in vec.iter() { p.print() }
1163 }
1164 fn main() {
1165 printAll([1, 2, 3]);
1166 }
1167 ~~~~
1168
1169 ## Dynamic Dispatch
1170
1171 ~~~~{.rust}
1172 fn print_all(vec: &[~Printable]) {
1173 for p in vec.iter() { p.print() }
1174 }
1175 fn main() {
1176 print_all([~1 as ~Printable, ~true as ~Printable]);
1177 }
1178 ~~~~
1179
1180 # Tasks and Communication
1181
1182 ## Tasks
1183
1184 ~~~~{.rust}
1185 fn main() {
1186 spawn(proc() {
1187 println!("Hello from another task!");
1188 });
1189 println!("Hello from the parent task!");
1190 }
1191 ~~~~
1192
1193 # Tasks and Communication
1194
1195 ## Communication
1196
1197 ~~~~{.rust}
1198 fn main() {
1199 let (port, chan): (Port<int>, Chan<int>) = Chan::new();
1200 spawn(proc() {
1201 chan.send(some_computation());
1202 });
1203 some_other_computation();
1204 let result = port.recv();
1205 }
1206 ~~~~
1207
1208 # Tasks and Communication
1209
1210 ## Atomic Reference Counting
1211
1212 ~~~~{.rust}
1213 fn main() {
1214 let parent_copy = Arc::new(something_very_large());
1215 let (port, chan) = Chan::new();
1216 chan.send(parent_copy.clone());
1217 spawn(proc() {
1218 let task_copy = port.recv();
1219 task_copy.get().do_something();
1220 });
1221 parent_copy.get().do_something_else();
1222 }
1223 ~~~~
1224
1225 # Tasks and Communication
1226
1227 ## Failure
1228
1229 ~~~~{.rust}
1230 fn main() {
1231 let r : Result<int, ()> = try(proc() {
1232 if some_operation_succeeds() {
1233 return 5;
1234 } else {
1235 fail!("Hark! An error!");
1236 }
1237 });
1238 match r {
1239 Ok(i) => println!("Got {}", i),
1240 Err(_) => println!("Hark!"),
1241 };
1242 }
1243 ~~~~
1244
1245 # Crates and Modules
1246
1247 - A "crate" is a compilation unit; `rustc` produces a single crate
1248 if it is run (either a library or an executable.)
1249 - A module is a grouping of definitions. Modules can be hierarchical
1250 and can be defined in a single file in `mod { ... }` blocks, or in
1251 separate files.
1252
1253 # Crates and Modules
1254
1255 ## main.rs
1256
1257 ~~~~{.rust}
1258 mod mylist {
1259 pub enum List<T> { Cons(T, ~List<T>), Nil }
1260 pub fn from_vec<T>(mut vec : ~[T]) -> ~List<T> { ... }
1261 impl<T> List<T> {
1262 pub fn length(&self) -> int { ... }
1263 }
1264 }
1265
1266 fn main() {
1267 let v = ~[1,2,3];
1268 let l = ::mylist::from_vec(v);
1269 /* ... */
1270 }
1271 ~~~~
1272
1273 # Crates and Modules
1274
1275 ## mylist.rs or mylist/mod.rs
1276
1277 ~~~~{.rust}
1278 mod mylist {
1279 pub enum List<T> { Cons(T, ~List<T>), Nil }
1280 pub fn from_vec<T>(mut vec : ~[T]) -> ~List<T> { ... }
1281 impl<T> List<T> {
1282 pub fn length(&self) -> int { ... }
1283 }
1284 }
1285 ~~~~
1286
1287 ## main.rs
1288
1289 ~~~~{.rust}
1290 mod mylist;
1291 main() {
1292 let v = ~[1,2,3];
1293 let l = ::mylist::from_vec(v);
1294 /* ... */
1295 }
1296 ~~~~
1297
1298 # Crates and Modules
1299 ## main.rs
1300
1301 ~~~~{.rust}
1302 use mylist::from_vec;
1303 mod mylist;
1304
1305 main() {
1306 let v = ~[1,2,3];
1307 let l = from_vec(v);
1308 /* ... */
1309 }
1310 ~~~~
1311
1312 # Crates and Modules
1313 ## Crate Metadata
1314
1315 ~~~~{.rust}
1316 #[crate_id = "mycrate#1.2"];
1317 #[crate_type = "lib"];
1318 ~~~~
1319
1320 ## Requesting Crate Metadata
1321
1322 ~~~~{.rust}
1323 extern crate mycrate "mycrate#1.2";
1324 extern crate oldmycrate "mycrate#0.6";
1325 ~~~~
1326
1327 # The Future
1328
1329 # The Future
1330
1331 \begin{center}
1332 \includegraphics[width=.9\textwidth]{imgs/flying-machines.jpg}
1333 \end{center}
1334
1335 # The Future
1336
1337 ## Possible Syntax Changes
1338
1339 - `~foo` might become `box foo`
1340 - `~[T]` might become `Vec<T>`
1341 - Operator overloading
1342
1343 ## Possible Language Changes
1344
1345 - Speculations about inheritance, subtyping
1346 - Stronger restrictions on `unsafe` code
1347
1348 ## Standard Library Improvements
1349
1350 ## Package Manager