# Functional Programming in Rust

I will be using some functional programming concepts in this tutorial. Those who have never performed functional programming before may need some explanation. The strength in functional programming lies within how simple it is to perform calculations on lists of variables, regardless of their data type. A list of variables is known as a vector in Rust, abbreviated to `Vec`. Using functional techniques, you can manipulate vectors with a single line of code. This is all performed without having to rely on the traditional and complicated for loop.

## Iterator Type

The `Iterator` type in Rust is used to perform much of the functional heavy-lifting. Any `Vec` of elements can be transformed into an `Iterator` using either the `iter()` or `into_iter()` functions. The former function, `iter()`, passes values of each element by reference to eliminate the need for copying, while `into_iter()` passes values by value -- copying each element.

``````let numbers_iterator = [0,2,3,4,5].iter();
``````

## Maps, Filters and Folds

The `Iterator` type contains basic methods such as `map()`, `filter()` and `fold()`, among many other highly useful methods. Maps apply a function to each element in a vector and return the result of each iteration to the next function. `Filters` works similarly only that it will only return elements that meet a certain criteria. Folds will apply a function whose purpose is to accumulate all the elements in the vector into a single value. At the end, the `collect()` function is used to return a new `Vec` of values.

``````let sum = numbers_iterator
.fold(0, |total, next| total + next);
let squared = (1..10).iter()
.map(|&x| x * x).collect();
``````

## How Iterator Works

You may think of methods like `map()`, `filter()` and `fold()` as specialized for loops that recurse across a vector using a series `next()` calls with a function or closure as the input to apply to each iteration. Each pass through these methods returns another `Iterator` type containing all of the results, so no matter how many methods you pass through, it will remain as an `Iterator` until it is collected with `collect()`.

## Lazy Programming

Because Rust uses a lazy model of functional programming, like Haskell, it only computes what it needs. It will only perform the minimal amount of calculations needed to obtain the results required.

In the following example, because `take(5)` was added after `filter()`, it will stop filtering after the fifth successful filter. It will then pass those five values to `map()` and each will be collected into a new `Vec` by `collect()`. Because of this, this is actually much more efficient than it seems at first glance to programmers that are used to programming in traditional non-lazy languages. This can actually be as fast as or even faster than a traditional for loop.

## Functional Programming With Numbers

``````fn main() {
let vector = (1..)            // Infinite range of integers
.filter(|x| x % 2 != 0)   // Collect odd numbers
.take(5)                  // Only take five numbers
.map(|x| x * x)           // Square each number
.collect::<Vec<usize>>(); // Return as a new Vec<usize>
println!("{:?}", vector);     // Print result
}
``````

## Functional Programming With Strings

``````fn main() {
let sentence = "This is a sentence in Rust.";
let words: Vec<&str> = sentence
.split_whitespace()
.collect();
let words_containing_i: Vec<&str> = words
.into_iter()
.filter(|word| word.contains("i"))
.collect();
println!("{:?}", words_containing_i);
}
``````

## See the Rust Book

Feel free to reference the official Rust documentation for the `String`, `Vec` and `Iterator` types. Many features aren't covered here since this program won't use them. I recommend trying out some functional programming as practice to get used to the idea. The official Rust Book is a good source of information as well.