summaryrefslogtreecommitdiffstats
path: root/src/doc/rust-by-example/src/fn
diff options
context:
space:
mode:
Diffstat (limited to 'src/doc/rust-by-example/src/fn')
-rw-r--r--src/doc/rust-by-example/src/fn/closures.md47
-rw-r--r--src/doc/rust-by-example/src/fn/closures/anonymity.md56
-rw-r--r--src/doc/rust-by-example/src/fn/closures/capture.md115
-rw-r--r--src/doc/rust-by-example/src/fn/closures/closure_examples.md3
-rw-r--r--src/doc/rust-by-example/src/fn/closures/closure_examples/iter_any.md54
-rw-r--r--src/doc/rust-by-example/src/fn/closures/closure_examples/iter_find.md81
-rw-r--r--src/doc/rust-by-example/src/fn/closures/input_functions.md38
-rw-r--r--src/doc/rust-by-example/src/fn/closures/input_parameters.md93
-rw-r--r--src/doc/rust-by-example/src/fn/closures/output_parameters.md56
-rw-r--r--src/doc/rust-by-example/src/fn/diverging.md69
-rw-r--r--src/doc/rust-by-example/src/fn/hof.md50
-rw-r--r--src/doc/rust-by-example/src/fn/methods.md118
12 files changed, 780 insertions, 0 deletions
diff --git a/src/doc/rust-by-example/src/fn/closures.md b/src/doc/rust-by-example/src/fn/closures.md
new file mode 100644
index 000000000..0c1b999ef
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/closures.md
@@ -0,0 +1,47 @@
+# Closures
+
+Closures are functions that can capture the enclosing environment. For
+example, a closure that captures the `x` variable:
+
+```Rust
+|val| val + x
+```
+
+The syntax and capabilities of closures make them very convenient for
+on the fly usage. Calling a closure is exactly like calling a function.
+However, both input and return types *can* be inferred and input
+variable names *must* be specified.
+
+Other characteristics of closures include:
+* using `||` instead of `()` around input variables.
+* optional body delimination (`{}`) for a single expression (mandatory otherwise).
+* the ability to capture the outer environment variables.
+
+```rust,editable
+fn main() {
+ // Increment via closures and functions.
+ fn function(i: i32) -> i32 { i + 1 }
+
+ // Closures are anonymous, here we are binding them to references
+ // Annotation is identical to function annotation but is optional
+ // as are the `{}` wrapping the body. These nameless functions
+ // are assigned to appropriately named variables.
+ let closure_annotated = |i: i32| -> i32 { i + 1 };
+ let closure_inferred = |i | i + 1 ;
+
+ let i = 1;
+ // Call the function and closures.
+ println!("function: {}", function(i));
+ println!("closure_annotated: {}", closure_annotated(i));
+ println!("closure_inferred: {}", closure_inferred(i));
+ // Once closure's type has been inferred, it cannot be inferred again with another type.
+ //println!("cannot reuse closure_inferred with another type: {}", closure_inferred(42i64));
+ // TODO: uncomment the line above and see the compiler error.
+
+ // A closure taking no arguments which returns an `i32`.
+ // The return type is inferred.
+ let one = || 1;
+ println!("closure returning one: {}", one());
+
+}
+```
diff --git a/src/doc/rust-by-example/src/fn/closures/anonymity.md b/src/doc/rust-by-example/src/fn/closures/anonymity.md
new file mode 100644
index 000000000..7008a446b
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/closures/anonymity.md
@@ -0,0 +1,56 @@
+# Type anonymity
+
+Closures succinctly capture variables from enclosing scopes. Does this have
+any consequences? It surely does. Observe how using a closure as a function
+parameter requires [generics], which is necessary because of how they are
+defined:
+
+```rust
+// `F` must be generic.
+fn apply<F>(f: F) where
+ F: FnOnce() {
+ f();
+}
+```
+
+When a closure is defined, the compiler implicitly creates a new
+anonymous structure to store the captured variables inside, meanwhile
+implementing the functionality via one of the `traits`: `Fn`, `FnMut`, or
+`FnOnce` for this unknown type. This type is assigned to the variable which
+is stored until calling.
+
+Since this new type is of unknown type, any usage in a function will require
+generics. However, an unbounded type parameter `<T>` would still be ambiguous
+and not be allowed. Thus, bounding by one of the `traits`: `Fn`, `FnMut`, or
+`FnOnce` (which it implements) is sufficient to specify its type.
+
+```rust,editable
+// `F` must implement `Fn` for a closure which takes no
+// inputs and returns nothing - exactly what is required
+// for `print`.
+fn apply<F>(f: F) where
+ F: Fn() {
+ f();
+}
+
+fn main() {
+ let x = 7;
+
+ // Capture `x` into an anonymous type and implement
+ // `Fn` for it. Store it in `print`.
+ let print = || println!("{}", x);
+
+ apply(print);
+}
+```
+
+### See also:
+
+[A thorough analysis][thorough_analysis], [`Fn`][fn], [`FnMut`][fn_mut],
+and [`FnOnce`][fn_once]
+
+[generics]: ../../generics.md
+[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html
+[fn_mut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html
+[fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html
+[thorough_analysis]: https://huonw.github.io/blog/2015/05/finding-closure-in-rust/
diff --git a/src/doc/rust-by-example/src/fn/closures/capture.md b/src/doc/rust-by-example/src/fn/closures/capture.md
new file mode 100644
index 000000000..061ef1c7b
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/closures/capture.md
@@ -0,0 +1,115 @@
+# Capturing
+
+Closures are inherently flexible and will do what the functionality requires
+to make the closure work without annotation. This allows capturing to
+flexibly adapt to the use case, sometimes moving and sometimes borrowing.
+Closures can capture variables:
+
+* by reference: `&T`
+* by mutable reference: `&mut T`
+* by value: `T`
+
+They preferentially capture variables by reference and only go lower when
+required.
+
+```rust,editable
+fn main() {
+ use std::mem;
+
+ let color = String::from("green");
+
+ // A closure to print `color` which immediately borrows (`&`) `color` and
+ // stores the borrow and closure in the `print` variable. It will remain
+ // borrowed until `print` is used the last time.
+ //
+ // `println!` only requires arguments by immutable reference so it doesn't
+ // impose anything more restrictive.
+ let print = || println!("`color`: {}", color);
+
+ // Call the closure using the borrow.
+ print();
+
+ // `color` can be borrowed immutably again, because the closure only holds
+ // an immutable reference to `color`.
+ let _reborrow = &color;
+ print();
+
+ // A move or reborrow is allowed after the final use of `print`
+ let _color_moved = color;
+
+
+ let mut count = 0;
+ // A closure to increment `count` could take either `&mut count` or `count`
+ // but `&mut count` is less restrictive so it takes that. Immediately
+ // borrows `count`.
+ //
+ // A `mut` is required on `inc` because a `&mut` is stored inside. Thus,
+ // calling the closure mutates the closure which requires a `mut`.
+ let mut inc = || {
+ count += 1;
+ println!("`count`: {}", count);
+ };
+
+ // Call the closure using a mutable borrow.
+ inc();
+
+ // The closure still mutably borrows `count` because it is called later.
+ // An attempt to reborrow will lead to an error.
+ // let _reborrow = &count;
+ // ^ TODO: try uncommenting this line.
+ inc();
+
+ // The closure no longer needs to borrow `&mut count`. Therefore, it is
+ // possible to reborrow without an error
+ let _count_reborrowed = &mut count;
+
+
+ // A non-copy type.
+ let movable = Box::new(3);
+
+ // `mem::drop` requires `T` so this must take by value. A copy type
+ // would copy into the closure leaving the original untouched.
+ // A non-copy must move and so `movable` immediately moves into
+ // the closure.
+ let consume = || {
+ println!("`movable`: {:?}", movable);
+ mem::drop(movable);
+ };
+
+ // `consume` consumes the variable so this can only be called once.
+ consume();
+ // consume();
+ // ^ TODO: Try uncommenting this line.
+}
+```
+
+Using `move` before vertical pipes forces closure
+to take ownership of captured variables:
+
+```rust,editable
+fn main() {
+ // `Vec` has non-copy semantics.
+ let haystack = vec![1, 2, 3];
+
+ let contains = move |needle| haystack.contains(needle);
+
+ println!("{}", contains(&1));
+ println!("{}", contains(&4));
+
+ // println!("There're {} elements in vec", haystack.len());
+ // ^ Uncommenting above line will result in compile-time error
+ // because borrow checker doesn't allow re-using variable after it
+ // has been moved.
+
+ // Removing `move` from closure's signature will cause closure
+ // to borrow _haystack_ variable immutably, hence _haystack_ is still
+ // available and uncommenting above line will not cause an error.
+}
+```
+
+### See also:
+
+[`Box`][box] and [`std::mem::drop`][drop]
+
+[box]: ../../std/box.md
+[drop]: https://doc.rust-lang.org/std/mem/fn.drop.html
diff --git a/src/doc/rust-by-example/src/fn/closures/closure_examples.md b/src/doc/rust-by-example/src/fn/closures/closure_examples.md
new file mode 100644
index 000000000..2455523ad
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/closures/closure_examples.md
@@ -0,0 +1,3 @@
+# Examples in `std`
+
+This section contains a few examples of using closures from the `std` library. \ No newline at end of file
diff --git a/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_any.md b/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_any.md
new file mode 100644
index 000000000..fe7fc39f8
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_any.md
@@ -0,0 +1,54 @@
+# Iterator::any
+
+`Iterator::any` is a function which when passed an iterator, will return
+`true` if any element satisfies the predicate. Otherwise `false`. Its
+signature:
+
+```rust,ignore
+pub trait Iterator {
+ // The type being iterated over.
+ type Item;
+
+ // `any` takes `&mut self` meaning the caller may be borrowed
+ // and modified, but not consumed.
+ fn any<F>(&mut self, f: F) -> bool where
+ // `FnMut` meaning any captured variable may at most be
+ // modified, not consumed. `Self::Item` states it takes
+ // arguments to the closure by value.
+ F: FnMut(Self::Item) -> bool;
+}
+```
+
+```rust,editable
+fn main() {
+ let vec1 = vec![1, 2, 3];
+ let vec2 = vec![4, 5, 6];
+
+ // `iter()` for vecs yields `&i32`. Destructure to `i32`.
+ println!("2 in vec1: {}", vec1.iter() .any(|&x| x == 2));
+ // `into_iter()` for vecs yields `i32`. No destructuring required.
+ println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2));
+
+ // `iter()` only borrows `vec1` and its elements, so they can be used again
+ println!("vec1 len: {}", vec1.len());
+ println!("First element of vec1 is: {}", vec1[0]);
+ // `into_iter()` does move `vec2` and its elements, so they cannot be used again
+ // println!("First element of vec2 is: {}", vec2[0]);
+ // println!("vec2 len: {}", vec2.len());
+ // TODO: uncomment two lines above and see compiler errors.
+
+ let array1 = [1, 2, 3];
+ let array2 = [4, 5, 6];
+
+ // `iter()` for arrays yields `&i32`.
+ println!("2 in array1: {}", array1.iter() .any(|&x| x == 2));
+ // `into_iter()` for arrays yields `i32`.
+ println!("2 in array2: {}", array2.into_iter().any(|x| x == 2));
+}
+```
+
+### See also:
+
+[`std::iter::Iterator::any`][any]
+
+[any]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.any
diff --git a/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_find.md b/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_find.md
new file mode 100644
index 000000000..0a79f7c9d
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/closures/closure_examples/iter_find.md
@@ -0,0 +1,81 @@
+# Searching through iterators
+
+`Iterator::find` is a function which iterates over an iterator and searches for the
+first value which satisfies some condition. If none of the values satisfy the
+condition, it returns `None`. Its signature:
+
+```rust,ignore
+pub trait Iterator {
+ // The type being iterated over.
+ type Item;
+
+ // `find` takes `&mut self` meaning the caller may be borrowed
+ // and modified, but not consumed.
+ fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
+ // `FnMut` meaning any captured variable may at most be
+ // modified, not consumed. `&Self::Item` states it takes
+ // arguments to the closure by reference.
+ P: FnMut(&Self::Item) -> bool;
+}
+```
+
+```rust,editable
+fn main() {
+ let vec1 = vec![1, 2, 3];
+ let vec2 = vec![4, 5, 6];
+
+ // `iter()` for vecs yields `&i32`.
+ let mut iter = vec1.iter();
+ // `into_iter()` for vecs yields `i32`.
+ let mut into_iter = vec2.into_iter();
+
+ // `iter()` for vecs yields `&i32`, and we want to reference one of its
+ // items, so we have to destructure `&&i32` to `i32`
+ println!("Find 2 in vec1: {:?}", iter .find(|&&x| x == 2));
+ // `into_iter()` for vecs yields `i32`, and we want to reference one of
+ // its items, so we have to destructure `&i32` to `i32`
+ println!("Find 2 in vec2: {:?}", into_iter.find(| &x| x == 2));
+
+ let array1 = [1, 2, 3];
+ let array2 = [4, 5, 6];
+
+ // `iter()` for arrays yields `&i32`
+ println!("Find 2 in array1: {:?}", array1.iter() .find(|&&x| x == 2));
+ // `into_iter()` for arrays yields `i32`
+ println!("Find 2 in array2: {:?}", array2.into_iter().find(|&x| x == 2));
+}
+```
+
+`Iterator::find` gives you a reference to the item. But if you want the _index_ of the
+item, use `Iterator::position`.
+
+```rust,editable
+fn main() {
+ let vec = vec![1, 9, 3, 3, 13, 2];
+
+ // `iter()` for vecs yields `&i32` and `position()` does not take a reference, so
+ // we have to destructure `&i32` to `i32`
+ let index_of_first_even_number = vec.iter().position(|&x| x % 2 == 0);
+ assert_eq!(index_of_first_even_number, Some(5));
+
+ // `into_iter()` for vecs yields `i32` and `position()` does not take a reference, so
+ // we do not have to destructure
+ let index_of_first_negative_number = vec.into_iter().position(|x| x < 0);
+ assert_eq!(index_of_first_negative_number, None);
+}
+```
+
+### See also:
+
+[`std::iter::Iterator::find`][find]
+
+[`std::iter::Iterator::find_map`][find_map]
+
+[`std::iter::Iterator::position`][position]
+
+[`std::iter::Iterator::rposition`][rposition]
+
+[find]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find
+[find_map]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find_map
+[position]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.position
+[rposition]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.rposition
diff --git a/src/doc/rust-by-example/src/fn/closures/input_functions.md b/src/doc/rust-by-example/src/fn/closures/input_functions.md
new file mode 100644
index 000000000..0cf9cd1cb
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/closures/input_functions.md
@@ -0,0 +1,38 @@
+# Input functions
+
+Since closures may be used as arguments, you might wonder if the same can be said
+about functions. And indeed they can! If you declare a function that takes a
+closure as parameter, then any function that satisfies the trait bound of that
+closure can be passed as a parameter.
+
+```rust,editable
+// Define a function which takes a generic `F` argument
+// bounded by `Fn`, and calls it
+fn call_me<F: Fn()>(f: F) {
+ f();
+}
+
+// Define a wrapper function satisfying the `Fn` bound
+fn function() {
+ println!("I'm a function!");
+}
+
+fn main() {
+ // Define a closure satisfying the `Fn` bound
+ let closure = || println!("I'm a closure!");
+
+ call_me(closure);
+ call_me(function);
+}
+```
+
+As an additional note, the `Fn`, `FnMut`, and `FnOnce` `traits` dictate how
+a closure captures variables from the enclosing scope.
+
+### See also:
+
+[`Fn`][fn], [`FnMut`][fn_mut], and [`FnOnce`][fn_once]
+
+[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html
+[fn_mut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html
+[fn_once]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html
diff --git a/src/doc/rust-by-example/src/fn/closures/input_parameters.md b/src/doc/rust-by-example/src/fn/closures/input_parameters.md
new file mode 100644
index 000000000..8f4307ff5
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/closures/input_parameters.md
@@ -0,0 +1,93 @@
+# As input parameters
+
+While Rust chooses how to capture variables on the fly mostly without type
+annotation, this ambiguity is not allowed when writing functions. When
+taking a closure as an input parameter, the closure's complete type must be
+annotated using one of a few `traits`, and they're determined by what the
+closure does with captured value. In order of decreasing restriction,
+they are:
+
+* `Fn`: the closure uses the captured value by reference (`&T`)
+* `FnMut`: the closure uses the captured value by mutable reference (`&mut T`)
+* `FnOnce`: the closure uses the captured value by value (`T`)
+
+On a variable-by-variable basis, the compiler will capture variables in the
+least restrictive manner possible.
+
+For instance, consider a parameter annotated as `FnOnce`. This specifies
+that the closure *may* capture by `&T`, `&mut T`, or `T`, but the compiler
+will ultimately choose based on how the captured variables are used in the
+closure.
+
+This is because if a move is possible, then any type of borrow should also
+be possible. Note that the reverse is not true. If the parameter is
+annotated as `Fn`, then capturing variables by `&mut T` or `T` are not
+allowed.
+
+In the following example, try swapping the usage of `Fn`, `FnMut`, and
+`FnOnce` to see what happens:
+
+```rust,editable
+// A function which takes a closure as an argument and calls it.
+// <F> denotes that F is a "Generic type parameter"
+fn apply<F>(f: F) where
+ // The closure takes no input and returns nothing.
+ F: FnOnce() {
+ // ^ TODO: Try changing this to `Fn` or `FnMut`.
+
+ f();
+}
+
+// A function which takes a closure and returns an `i32`.
+fn apply_to_3<F>(f: F) -> i32 where
+ // The closure takes an `i32` and returns an `i32`.
+ F: Fn(i32) -> i32 {
+
+ f(3)
+}
+
+fn main() {
+ use std::mem;
+
+ let greeting = "hello";
+ // A non-copy type.
+ // `to_owned` creates owned data from borrowed one
+ let mut farewell = "goodbye".to_owned();
+
+ // Capture 2 variables: `greeting` by reference and
+ // `farewell` by value.
+ let diary = || {
+ // `greeting` is by reference: requires `Fn`.
+ println!("I said {}.", greeting);
+
+ // Mutation forces `farewell` to be captured by
+ // mutable reference. Now requires `FnMut`.
+ farewell.push_str("!!!");
+ println!("Then I screamed {}.", farewell);
+ println!("Now I can sleep. zzzzz");
+
+ // Manually calling drop forces `farewell` to
+ // be captured by value. Now requires `FnOnce`.
+ mem::drop(farewell);
+ };
+
+ // Call the function which applies the closure.
+ apply(diary);
+
+ // `double` satisfies `apply_to_3`'s trait bound
+ let double = |x| 2 * x;
+
+ println!("3 doubled: {}", apply_to_3(double));
+}
+```
+
+### See also:
+
+[`std::mem::drop`][drop], [`Fn`][fn], [`FnMut`][fnmut], [Generics][generics], [where][where] and [`FnOnce`][fnonce]
+
+[drop]: https://doc.rust-lang.org/std/mem/fn.drop.html
+[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html
+[fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html
+[fnonce]: https://doc.rust-lang.org/std/ops/trait.FnOnce.html
+[generics]: ../../generics.md
+[where]: ../../generics/where.md
diff --git a/src/doc/rust-by-example/src/fn/closures/output_parameters.md b/src/doc/rust-by-example/src/fn/closures/output_parameters.md
new file mode 100644
index 000000000..6cad1735b
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/closures/output_parameters.md
@@ -0,0 +1,56 @@
+# As output parameters
+
+Closures as input parameters are possible, so returning closures as
+output parameters should also be possible. However, anonymous
+closure types are, by definition, unknown, so we have to use
+`impl Trait` to return them.
+
+The valid traits for returning a closure are:
+
+* `Fn`
+* `FnMut`
+* `FnOnce`
+
+Beyond this, the `move` keyword must be used, which signals that all captures
+occur by value. This is required because any captures by reference would be
+dropped as soon as the function exited, leaving invalid references in the
+closure.
+
+```rust,editable
+fn create_fn() -> impl Fn() {
+ let text = "Fn".to_owned();
+
+ move || println!("This is a: {}", text)
+}
+
+fn create_fnmut() -> impl FnMut() {
+ let text = "FnMut".to_owned();
+
+ move || println!("This is a: {}", text)
+}
+
+fn create_fnonce() -> impl FnOnce() {
+ let text = "FnOnce".to_owned();
+
+ move || println!("This is a: {}", text)
+}
+
+fn main() {
+ let fn_plain = create_fn();
+ let mut fn_mut = create_fnmut();
+ let fn_once = create_fnonce();
+
+ fn_plain();
+ fn_mut();
+ fn_once();
+}
+```
+
+### See also:
+
+[`Fn`][fn], [`FnMut`][fnmut], [Generics][generics] and [impl Trait][impltrait].
+
+[fn]: https://doc.rust-lang.org/std/ops/trait.Fn.html
+[fnmut]: https://doc.rust-lang.org/std/ops/trait.FnMut.html
+[generics]: ../../generics.md
+[impltrait]: ../../trait/impl_trait.md
diff --git a/src/doc/rust-by-example/src/fn/diverging.md b/src/doc/rust-by-example/src/fn/diverging.md
new file mode 100644
index 000000000..52e1f819a
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/diverging.md
@@ -0,0 +1,69 @@
+# Diverging functions
+
+Diverging functions never return. They are marked using `!`, which is an empty type.
+
+```rust
+fn foo() -> ! {
+ panic!("This call never returns.");
+}
+```
+
+As opposed to all the other types, this one cannot be instantiated, because the
+set of all possible values this type can have is empty. Note that, it is
+different from the `()` type, which has exactly one possible value.
+
+For example, this function returns as usual, although there is no information
+in the return value.
+
+```rust
+fn some_fn() {
+ ()
+}
+
+fn main() {
+ let a: () = some_fn();
+ println!("This function returns and you can see this line.")
+}
+```
+
+As opposed to this function, which will never return the control back to the caller.
+
+```rust,ignore
+#![feature(never_type)]
+
+fn main() {
+ let x: ! = panic!("This call never returns.");
+ println!("You will never see this line!");
+}
+```
+
+Although this might seem like an abstract concept, it is in fact very useful and
+often handy. The main advantage of this type is that it can be cast to any other
+one and therefore used at places where an exact type is required, for instance
+in `match` branches. This allows us to write code like this:
+
+```rust
+fn main() {
+ fn sum_odd_numbers(up_to: u32) -> u32 {
+ let mut acc = 0;
+ for i in 0..up_to {
+ // Notice that the return type of this match expression must be u32
+ // because of the type of the "addition" variable.
+ let addition: u32 = match i%2 == 1 {
+ // The "i" variable is of type u32, which is perfectly fine.
+ true => i,
+ // On the other hand, the "continue" expression does not return
+ // u32, but it is still fine, because it never returns and therefore
+ // does not violate the type requirements of the match expression.
+ false => continue,
+ };
+ acc += addition;
+ }
+ acc
+ }
+ println!("Sum of odd numbers up to 9 (excluding): {}", sum_odd_numbers(9));
+}
+```
+
+It is also the return type of functions that loop forever (e.g. `loop {}`) like
+network servers or functions that terminate the process (e.g. `exit()`).
diff --git a/src/doc/rust-by-example/src/fn/hof.md b/src/doc/rust-by-example/src/fn/hof.md
new file mode 100644
index 000000000..88918cb52
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/hof.md
@@ -0,0 +1,50 @@
+# Higher Order Functions
+
+Rust provides Higher Order Functions (HOF). These are functions that
+take one or more functions and/or produce a more useful function. HOFs
+and lazy iterators give Rust its functional flavor.
+
+```rust,editable
+fn is_odd(n: u32) -> bool {
+ n % 2 == 1
+}
+
+fn main() {
+ println!("Find the sum of all the squared odd numbers under 1000");
+ let upper = 1000;
+
+ // Imperative approach
+ // Declare accumulator variable
+ let mut acc = 0;
+ // Iterate: 0, 1, 2, ... to infinity
+ for n in 0.. {
+ // Square the number
+ let n_squared = n * n;
+
+ if n_squared >= upper {
+ // Break loop if exceeded the upper limit
+ break;
+ } else if is_odd(n_squared) {
+ // Accumulate value, if it's odd
+ acc += n_squared;
+ }
+ }
+ println!("imperative style: {}", acc);
+
+ // Functional approach
+ let sum_of_squared_odd_numbers: u32 =
+ (0..).map(|n| n * n) // All natural numbers squared
+ .take_while(|&n_squared| n_squared < upper) // Below upper limit
+ .filter(|&n_squared| is_odd(n_squared)) // That are odd
+ .sum(); // Sum them
+ println!("functional style: {}", sum_of_squared_odd_numbers);
+}
+```
+
+[Option][option]
+and
+[Iterator][iter]
+implement their fair share of HOFs.
+
+[option]: https://doc.rust-lang.org/core/option/enum.Option.html
+[iter]: https://doc.rust-lang.org/core/iter/trait.Iterator.html
diff --git a/src/doc/rust-by-example/src/fn/methods.md b/src/doc/rust-by-example/src/fn/methods.md
new file mode 100644
index 000000000..bd5d997f0
--- /dev/null
+++ b/src/doc/rust-by-example/src/fn/methods.md
@@ -0,0 +1,118 @@
+# Associated functions & Methods
+
+Some functions are connected to a particular type. These come in two forms:
+associated functions, and methods. Associated functions are functions that
+are defined on a type generally, while methods are associated functions that are
+called on a particular instance of a type.
+
+```rust,editable
+struct Point {
+ x: f64,
+ y: f64,
+}
+
+// Implementation block, all `Point` associated functions & methods go in here
+impl Point {
+ // This is an "associated function" because this function is associated with
+ // a particular type, that is, Point.
+ //
+ // Associated functions don't need to be called with an instance.
+ // These functions are generally used like constructors.
+ fn origin() -> Point {
+ Point { x: 0.0, y: 0.0 }
+ }
+
+ // Another associated function, taking two arguments:
+ fn new(x: f64, y: f64) -> Point {
+ Point { x: x, y: y }
+ }
+}
+
+struct Rectangle {
+ p1: Point,
+ p2: Point,
+}
+
+impl Rectangle {
+ // This is a method
+ // `&self` is sugar for `self: &Self`, where `Self` is the type of the
+ // caller object. In this case `Self` = `Rectangle`
+ fn area(&self) -> f64 {
+ // `self` gives access to the struct fields via the dot operator
+ let Point { x: x1, y: y1 } = self.p1;
+ let Point { x: x2, y: y2 } = self.p2;
+
+ // `abs` is a `f64` method that returns the absolute value of the
+ // caller
+ ((x1 - x2) * (y1 - y2)).abs()
+ }
+
+ fn perimeter(&self) -> f64 {
+ let Point { x: x1, y: y1 } = self.p1;
+ let Point { x: x2, y: y2 } = self.p2;
+
+ 2.0 * ((x1 - x2).abs() + (y1 - y2).abs())
+ }
+
+ // This method requires the caller object to be mutable
+ // `&mut self` desugars to `self: &mut Self`
+ fn translate(&mut self, x: f64, y: f64) {
+ self.p1.x += x;
+ self.p2.x += x;
+
+ self.p1.y += y;
+ self.p2.y += y;
+ }
+}
+
+// `Pair` owns resources: two heap allocated integers
+struct Pair(Box<i32>, Box<i32>);
+
+impl Pair {
+ // This method "consumes" the resources of the caller object
+ // `self` desugars to `self: Self`
+ fn destroy(self) {
+ // Destructure `self`
+ let Pair(first, second) = self;
+
+ println!("Destroying Pair({}, {})", first, second);
+
+ // `first` and `second` go out of scope and get freed
+ }
+}
+
+fn main() {
+ let rectangle = Rectangle {
+ // Associated functions are called using double colons
+ p1: Point::origin(),
+ p2: Point::new(3.0, 4.0),
+ };
+
+ // Methods are called using the dot operator
+ // Note that the first argument `&self` is implicitly passed, i.e.
+ // `rectangle.perimeter()` === `Rectangle::perimeter(&rectangle)`
+ println!("Rectangle perimeter: {}", rectangle.perimeter());
+ println!("Rectangle area: {}", rectangle.area());
+
+ let mut square = Rectangle {
+ p1: Point::origin(),
+ p2: Point::new(1.0, 1.0),
+ };
+
+ // Error! `rectangle` is immutable, but this method requires a mutable
+ // object
+ //rectangle.translate(1.0, 0.0);
+ // TODO ^ Try uncommenting this line
+
+ // Okay! Mutable objects can call mutable methods
+ square.translate(1.0, 1.0);
+
+ let pair = Pair(Box::new(1), Box::new(2));
+
+ pair.destroy();
+
+ // Error! Previous `destroy` call "consumed" `pair`
+ //pair.destroy();
+ // TODO ^ Try uncommenting this line
+}
+```