+// You can change `main` to call this function, and you should notice - nothing, no difference in
+// behavior. But we wrote much less boilerplate code!
+
+// Remember that we decided to use the `FnMut` trait above? This means our closure could actually
+// mutate its environment. For example, we can use that to count the digits as they are printed.
+pub fn print_and_count(b: &BigInt) {
+ let mut count: usize = 0;
+ //@ This time, the environment will contain a field of type `&mut usize`, that will be
+ //@ initialized with a mutable reference of `count`. The closure, since it mutably borrows its
+ //@ environment, is able to access this field and mutate `count` through it. Once `act`
+ //@ returns, the closure is destroyed and `count` is no longer borrowed.
+ //@ Because closures compile down to normal types, all the borrow checking continues to work as
+ //@ usually, and we cannot accidentally leak a closure somewhere that still contains, in its
+ //@ environment, a dead reference.
+ b.act(|digit| { println!("{}: {}", count, digit); count = count +1; } );
+ println!("There are {} digits", count);
+}
+
+// ## Fun with iterators and closures
+//@ If you are familiar with functional languages, you are probably aware that one can have lots of
+//@ fun with iterators and closures. Rust provides a whole lot of methods on iterators that allow
+//@ us to write pretty functional-style list manipulation.
+
+// Let's say we want to write a function that increments every entry of a `Vec` by some number,
+// then looks for numbers larger than some threshold, and prints them.
+fn inc_print_threshold(v: &Vec<i32>, offset: i32, threshold: i32) {
+ //@ `map` takes a closure that is applied to every element of the iterator. `filter` removes
+ //@ elements from the iterator that do not pass the test given by the closure.
+ //@
+ //@ Since all these closures compile down to the pattern described above, there is actually no
+ //@ heap allocation going on here. This makes closures very efficient, and it makes
+ //@ optimization fairly trivial: The resulting code will look like you hand-rolled the loop in
+ //@ C.
+ for i in v.iter().map(|n| *n + offset).filter(|n| *n > threshold) {
+ println!("{}", i);
+ }
+}
+
+// Sometimes it is useful to know both the position of some element in a list, and its value.
+// That's where the `enumerate` function helps.
+fn print_enumerated<T: fmt::Display>(v: &Vec<T>) {
+ //@ `enumerate` turns an iterator over `T` into an iterator over `(usize, T)`, where the first
+ //@ element just counts the position in the iterator. We can do pattern matching right in the
+ //@ loop header to obtain names for both the position, and the value.
+ for (i, t) in v.iter().enumerate() {
+ println!("Position {}: {}", i, t);
+ }
+}
+
+// And as a final example, one can also collect all elements of an iterator, and put them, e.g., in a vector.
+fn filter_vec_by_divisor(v: &Vec<i32>, divisor: i32) -> Vec<i32> {
+ //@ Here, the return type of `collect` is inferred based on the return type of our function. In
+ //@ general, it can return anything implementing
+ //@ [`FromIterator`](https://doc.rust-lang.org/stable/std/iter/trait.FromIterator.html).
+ //@ Notice that `iter` gives us an iterator over borrowed `i32`, but we want to own them for
+ //@ the result, so we insert a `map` to dereference.
+ v.iter().map(|n| *n).filter(|n| *n % divisor == 0).collect() /*@*/
+}
+
+// **Exercise 10.1**: Look up the
+// [documentation of `Iterator`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html)
+// to learn about more functions that can act on iterators. Try using some of them. What about a
+// function that sums the even numbers of an iterator? Or a function that computes the product of
+// those numbers that sit at odd positions? A function that checks whether a vector contains a
+// certain number? Whether all numbers are smaller than some threshold? Be creative!