Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.

Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.

Successfully reported this slideshow.

Like this presentation? Why not share!

- Rust Synchronization Primitives by Corey Richardson 2326 views
- Performance Comparison of Mutex, RW... by Mitsunori Komatsu 2319 views
- Signposts by Heidi Howard 789 views
- What the &~#@<!? (Memory Managem... by David Evans 3908 views
- OOP in Rust by KENZ_gelsoft 3657 views
- Redox OS by Norbert Melzer 834 views

902 views

Published on

Published in:
Software

No Downloads

Total views

902

On SlideShare

0

From Embeds

0

Number of Embeds

0

Shares

0

Downloads

16

Comments

0

Likes

1

No embeds

No notes for slide

- 1. HEY!There’s OCaml In My Rust! Kel Cecil @praisechaos
- 2. I ❤ Languages
- 3. Incredible Shrinking Operating System Steve Jones DevOps Days 2015
- 4. OCaml is pretty cool!
- 5. It's a functional programming language... # let double x = x * 2 in List.map double [ 1; 2; 3 ];; - : int list = [2; 4; 6] • OCaml is an almost pure functional programming language by default. • Functions are first-class citizens.
- 6. ... and an imperative programming language... let update_collectable_value order new_value = order.old_value <- order.current_value; order.current_value <- new_value; order • It can be convenient to be able to code in the imperative style. • OCaml includes imperative constructs like for and while loops.
- 7. ... and an object-oriented language! class ['a] queue init = object val mutable q: 'a list = init method enqueue item = q <- q @ item end;; • OCaml can also be object-oriented if needed.
- 8. OCaml powers some pretty sweet stuff. • MirageOS: Unikernel tech recently acquired by Docker • Flow: A static type checker for JavaScript • Hack: A programming languages for Facebook's HHVM • and...
- 9. Rust's first compiler! • rustboot was written in OCaml • Replaced for Rust 0.7
- 10. Rust is pretty excellent too! • Guaranteed Memory Safety • Threads without data races • Incredibly fast • Crazy awesome potential
- 11. Rust was inspired by OCaml in a few interesting ways!
- 12. Let's start with a simple, imperative OCaml program • Define a type named collectable_value that olds the previous value and current value of an item. • Provide a function to update the current value and update the old value. • Have a "main" function to create the record and update the value.
- 13. Starting with our type type collectable_value = { mutable old_value: ﬂoat; mutable current_value: ﬂoat; } • A record is a collection of values stored together as a data type. • Values are immutable by default but can be marked as mutable.
- 14. Adding our first function let update_collectable_value collectable new_value = collectable.old_value <- collectable.current_value; collectable.current_value <- new_value; collectable • Define a function with a let-binding. • Accepts a collectablevalue record (collectable) and a float (newvalue). • Updates and returns the record.
- 15. Adding a "main" let _ = let pinball_machine = { old_value = 0.0; current_value = 800.00; } in update_collectable_value pinball_machine 900.0 • Underscore discards the return value. • This let-binding allows us to execute code at the top level.
- 16. Anything seem a little Rust-y to you? type collectable_value = { mutable old_value: ﬂoat; mutable current_value: ﬂoat; } let update_collectable_value order new_value = order.old_value <- order.current_value; order.current_value <- new_value; order let _ = let pinball_machine = { old_value = 0.0; current_value = 800.00; } in update_collectable_value pinball_machine 900.0
- 17. Semicolon Separation in OCaml let update_collectable_value collectable new_value = collectable.old_value <- collectable.current_value; collectable.current_value <- new_value; collectable • Notice the semi-colons separating the expressions? • The last expression is the return value for the function. • Look familiar?
- 18. Statements in Rust fn greeting() -> String { let greeting = "Hello, there!"; String::from(greeting) // Return value from fn } • Rust code is mostly statements. • Most common statements are • declaring a variable • using an expression with a semi-colon • Last expression omitting the semi-colon is returned.
- 19. What is Type Inference? • Automatic deduction of the data type of an expression.
- 20. Rust's Type Inference // Rust knows that name is a String. let name = "Kel!" • Rust's type inference is loosely based on the Hindley-Milner algorithm4 . • Extensions were added to use accommodate subtyping. 4 https://github.com/rust-lang/rust/blob/master/src/librustc/infer/README.md
- 21. OCaml's Type Inference (* OCaml also knows this is a string. *) let name = "Kel!" • ML originally used the Hindley-Milner algorithm. • OCaml's implementation works through solving constraints. • Tons of research hours poured into their algorithm(s)5 5 https://www.cis.upenn.edu/~sweirich/icfp-plmw15/slides/pottier.pdf
- 22. Workshop: Binary Search Tree • Follow along in your IDEs! • Learn about binary search trees here: • https://en.wikipedia.org/wiki/Binary_search_tree • Check out the examples • https://github.com/kelcecil/rust-ocaml-workshop
- 23. Building our Tree Structure OCaml, then Rust.
- 24. Tree in OCaml type tree;; • Types in OCaml are defined with the type keyword.
- 25. Tree in OCaml type tree = Empty ;; • We need to represent a node that does not exist. • We'll represent this as Empty.
- 26. Tree in OCaml type tree = | Empty | Node ;; • We also want to represent a node that exists. • We'll represent this as node.
- 27. Tree in OCaml type 'a tree = | Empty | Node of 'a * 'a tree * 'a tree ;; • Our node must have a key, a left child, and a right child. • Node now contains generic 'a that is our key. • We also have two values of tree presenting our left and right leaves.
- 28. Algebraic Data Types • Composite type formed from other types • Common types of Algebraic Types • Product Types • Sum Types
- 29. Product Types • Compound types in a structure • Operands of the product are types • Structure is determined by fixed order of operands
- 30. (* Record *) type person = {name: string; age: int};; let kel = {name = "Kel"; age = 30};; (* Tuple *) let next_obsession = ("Dead Rising 4", 59.99);; Tuples and records are product types in OCaml
- 31. let my_love = ("Rust", 9001) • Tuples are product types in Rust • There's also the unit () type • Tuple with no operands.
- 32. Sum Types type 'a tree = | Empty | Node of 'a * 'a tree * 'a tree ;; • Multiple classes of values called variants. • Each class has it's own constructor. • Class represents it's own concept
- 33. Tree in Rust enum Tree { Empty } • Algebraic data types are enums in Rust. • We start with defining Empty.
- 34. enum Tree<T>{ Empty, Node(T, Box<Tree<T>>, Box<Tree<T>>) } • Node is a generic variable for the key, a left leaf, and a right leaf. • Recursive structures must be boxed1 . • We want the size of the Tree to be bounded. • Pointer using Box allocates memory on the heap. 1 https://doc.rust-lang.org/std/boxed/
- 35. Recap: Rust and OCaml Tree Structures6 type 'a tree = | Empty | Node of 'a * 'a tree * 'a tree ;; enum Tree<T>{ Empty, Node(T, Box<Tree<T>>, Box<Tree<T>>) } 6 https://github.com/kelcecil/rust-ocaml-workshop/tree/master/workshop/01-structure
- 36. Writing a depth function
- 37. depth (OCaml using Pattern Matching) let rec depth tree = match tree with | Empty -> 0 | Node(_, left, right) -> 1 + max (depth left) (depth right) ;; • let defines a variable or function in OCaml. • rec denotes a recursive function. • The match keyword matches by data type.
- 38. depth (OCaml using function) let rec depth = function | Empty -> 0 | Node(_, left, right) -> 1 + max (depth left) (depth right) ;; • OCaml functions can also be defined using the function keyword. • function has built in pattern matching for types. • This syntax is a bit more concise.
- 39. Unit Test for depth (OCaml) open OUnit (* tree type here *) (* depth function here *) let test_tree = Node(5, Node(3, Empty, Empty), Empty) let tree_depth _ = assert_equal 2 (depth test_tree) let suite = "Binary Tree Tests" >::: ["tree_depth" >:: tree_depth] let _ = run_test_tt_main suite
- 40. Running OCaml Tests ocamlﬁnd ocamlc -package oUnit -linkpkg -o <output_binary> <source_ﬁle>
- 41. depth (Rust) impl<T> Tree<T> where T: PartialOrd { fn depth(&self) -> usize { match *self { Tree::Empty => 0, Tree::Node(_, ref left, ref right) => 1 + max(left.depth(), right.depth()) } } } • Restricting our generic to PartialOrd lets us choose our key type similarly to OCaml.
- 42. Unit Test for depth (Rust) #[test] fn depth_test() { let tree = Tree::Node(5, Box::new( Tree::Node(4,Box::new(Tree::Empty), Box::new(Tree::Empty) )), Box::new(Tree::Empty)); assert!(tree.depth() == 2) }
- 43. Running Rust Unit Tests rustc --test <source_ﬁle>
- 44. tl;dr • OCaml's inspiration for Rust can been seen in: • Semicolon Statement Separation • Type Inference • Algebraic Data Types • Pattern Matching • Rust and OCaml are both totally awesome.
- 45. Time for you to try! • Adjust the our tree implementations to hold values. • Write insert functions for OCaml and Rust! • Write member functions for OCaml and Rust!
- 46. Stumped? No problem. • https://github.com/kelcecil/rust-ocaml-workshop • Clone the repository and experiment! • Check out the other random examples in the repository. • Ask for help!
- 47. Branching in OCaml OCaml has an if statement like so2 : if <boolean_condition> then <expression> else if <boolean_condition> then <expression> else <expression> 2 https://ocaml.org/learn/tutorials/ifstatementsloopsandrecursion.html

No public clipboards found for this slide

Be the first to comment