diff --git a/book/book.toml b/book/book.toml
index 78ab4a0e5be49a0c31d47f9e83483f922c1b1294..767af31f2e9bf7eec1efa6f47bd121ed1e1efb36 100644
--- a/book/book.toml
+++ b/book/book.toml
@@ -5,6 +5,9 @@ multilingual = false
 src = "src"
 title = "Rust-101: Université d'été"
 
+[output.html]
+mathjax-support = true
+
 [output.html.playground]
 editable = true
 
diff --git a/book/src/part10.md b/book/src/part10.md
index 1acace90d165643b41b496ef1c9c50e80ba5f0af..e4839da58b3d91a5d308b4d082b9510b978b35fd 100644
--- a/book/src/part10.md
+++ b/book/src/part10.md
@@ -1 +1,238 @@
-# Pointeurs intelligents et mémoire
\ No newline at end of file
+# Discussion du code `part10`
+
+## Concepts
+
+Les concepts abordés dans cet exemple sont:
+
+- [Discussion du code `part10`](#discussion-du-code-part10)
+  - [Concepts](#concepts)
+  - [Documentation](#documentation)
+  - [Discussion](#discussion)
+    - [Le trait itérateur](#le-trait-itérateur)
+    - [Les fonctions `iter` et `collect`](#les-fonctions-iter-et-collect)
+    - [Quelques fonctions d'ordre supérieur sur les itérateurs](#quelques-fonctions-dordre-supérieur-sur-les-itérateurs)
+    - [Performances et lazy evaluation](#performances-et-lazy-evaluation)
+  - [Rustlings](#rustlings)
+    - [Les itérateurs](#les-itérateurs)
+
+## Documentation
+
+Afin de compléter ce cours, je vous recommande la lecture des ressources suivantes :
+
+- [Traitements des collections avec de itérateurs en Rust](https://doc.rust-lang.org/book/ch13-02-iterators.html)
+- [Le trait Iterator en Rust](https://doc.rust-lang.org/std/iter/trait.Iterator.html)
+- [Les méthodes du trait Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html#provided-methods)
+
+## Discussion
+
+### Le trait itérateur
+
+L'itérateur est un patron de conception extrêment répandu en prorgrammation orientée objet. On le retrouve
+dans plusieurs langages comme par exemple python.
+
+Le trait `Iterator` est défini ainsi en version simplifiée dans la documentation :
+
+```rust
+trait Iterator {
+    type Item;
+    fn next(&mut self) -> Option<Self::Item>;
+}
+```
+
+Un itérateur possède donc un élément courant et une méthode `next()` qui permet de passer à l'élément suivant,
+puis de retourner l'élément courant. Un itérateur peut-être fini ou infini. Il peut permettre par exemple de
+parcourir une collection ou de créer un compteur. 
+
+La documentation Rust offre [un exemple d'implémentation d'itérateur assez accessible](https://doc.rust-lang.org/std/iter/index.html#implementing-iterator).
+
+### Les fonctions `iter` et `collect`
+
+Le Rust propose des méthodes permettant de passer d'une collection à un itérateur assez facilement.
+
+```rust
+# fn main(){
+    let v : Vec<i32> = vec![1,2,3,4];
+    let mut v_iter = v.iter();
+
+    println!("{}", v_iter.next().unwrap());
+    println!("{}", v_iter.next().unwrap());
+    println!("{}", v_iter.next().unwrap());
+    println!("{}", v_iter.next().unwrap());
+    assert!(v_iter.next().is_none());
+# }
+```
+
+La méthode `iter()` des vecteurs permet de créer un itérateur à partir d'un vecteur. Il faut noter que `v_iter` est mutable, car son état interne est **modifié** par l'appel à la méthode `next()`.
+En effet, pour pouvoir avancer dans notre itérateur, nous utilisons la fonction `next()` qui avance l'élément courant d'une position
+et retourne une `Option` sur l'élément courant. Pour rappel, la signature de la méthode de `next()` est `fn next(&mut self) -> Option<Self::Item>;`.
+
+Il est aussi possible de transformer un itérateur en collection à l'aide de la méthode `collect()`. La fonction `from_fn()` permet
+de créer un itérateur à l'aide d'une fonction :
+
+```rust
+# fn main(){
+  let mut count = 0;
+  let even_counter = std::iter::from_fn(|| {
+    count += 2;
+    Some(count)
+  });
+
+  let v : Vec<i32> = even_counter.take(3).collect();
+  println!("Les 3 premiers nombres paires sont {}, {}, {}", v[0], v[1], v[2])
+# }
+```
+
+Le code ci-dessus commence par créer un itérateur infini de nombres paires. Nous verrons plus-tard que les éléments de l'itérateur infini n'est pas généré immédiatement
+[dans la section lazy-evaluation](#performances-et-lazy-evaluation).
+Nous utilisons une variable mutable `count`, afin de générer les valeurs de notre itérateur.
+Notre closure va capturer cette variable et l'incrémenter de 2 à chaque appel et retourner la valeur courante encapsulée dans une `Option`.
+
+Notre itérateur étant infini, nous devons le limiter à un nombre fini d'éléments avant de pouvoir récupérer une collection.
+Pour cela nous utilisons la méthode `take()` qui permet de limiter la taille de notre itérateur. Finalement, nous pouvons
+récupérer un vecteur d'entier à l'aide de la méthode `collect()`.
+
+### Quelques fonctions d'ordre supérieur sur les itérateurs
+
+L'intérêt principal des itérateurs en Rust réside dans ses fonctions d'ordre supérieur. Elle permettent de traiter des collections
+de manière efficaces en apportant des garanties notament en terme de concurrence. On retrouve notament le crate
+[Rayon-rs](https://github.com/rayon-rs/rayon) qui permet d'effectuer des traitement en parallèle sans apporter de modifications
+majeures au code.
+
+Ici, nous nous concentrerons sur les méthodes suivantes qui sont très communes dans les langages fonctionnels (pas toujours avec les mêmes noms) :
+
+- `map()`
+- `filter()`
+- `fold()`
+- `zip()`
+
+Reprenons notre code de recherche du minimum d'une liste :
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part10/src/find.rs:find_minimum}}
+```
+
+Notre fonction prend en argument un vecteur `v` que nous transformons en itérateur avec la méthode `iter()`. Pour trouver le minimum
+de notre itérateur, nous utilisons la méthode `fold()`. Cette méthode permet de réduire un itérateur en appliquant itérativement,
+une fonction qui prend deux arguments et qui retourne un seul élément. On se retrouve donc avec une
+seule valeur à la fin de la réduction.  
+
+La méthode `fold()` prend donc deux arguments. Le premier est la valeur d'initialisation de notre réduction. On parle parfois d'élément neutre,
+mais ce terme est plus restrictif qu'une simple valeur initiale.
+
+L'élément neutre d'une opération est l'élément `N` qui si on lui applique l'opération avec n'importe quel autre élément `x` retourne
+cet élément `x`. Si nous prenons l'exemple de l'addition, l'élément neutre est 0, car :
+$$ 0 + x = x + 0 = x $$
+et ce peu importe la valeur de x. Il est préférable d'utiliser un élément neutre, plutôt qu'une valeur quelconque pour l'initialisation
+de notre réduction. Sans rentrer dans les détails, qui dépassent le cadre de ce cours, les algoritmes parallèles de réduction reposent
+sur l'usage d'un élément neutre. Utiliser un élément neutre, vous permettra donc de parallèliser votre code bien plus simplement.
+
+En l'occurence puisqu'on veut retourner une option, notre élément neutre est `None`.
+
+Le deuxième argument de notre fonction `fold()` est l'opération de réduction que nous utiliserons pour trouver le minimum. Pour cela nous
+utilisons une closure. Cette dernière prend deux argument, un accumulateur (la valeur courante de la réduction) de type `Option<i32>`
+et un l'élément courant de l'itérateur qui est de type `&i32`. Notre closure va simplement retourner une Option contenant l'élément le
+plus petit entre la valeur actuelle de l'accumulateur et la valeur courante. Cette valeur devient la nouvelle valeur de l'accumulateur
+pour l'appel suivant.
+
+Le résultat de la méthode `fold()` est la dernière valeur de l'accumulateur. Si l'itérateur est vide, la méthode `fold()` retournera la valeur
+d'initialisation. Dans notre cas, il s'agit d'une `Option` vide.
+
+Pour illustrer l'usage de la méthode `filter()`, nous avons une fonction qui trouve le plus petit nombre pair dans un vecteur :
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part10/src/find.rs:find_even_minimum}}
+```
+
+La méthode est similaire à la recherche du minimum, mais afin de garder uniquement les nombres pairs on ajoute la fonction `filter()`. Quand on ajoute ainsi
+une série de traitements à la suite, on parle de pipelines. 
+
+La fonction `filter()` prend une fonction en paramètre appelée prédicat. Un prédicat et une fonction qui prend un élément et retourne un booléen.
+Cette fonction va déterminer quels éléments conserver. Ici nous utilisons une closure qui retourne `true` si le nombre est pair. La méthode `filter()`
+va retourner un nouvel itérateur composé uniquement des éléments séléctionnés par le prédicat.
+
+Pour finir, on recherche la valeur minimum de ce nouvel itérateur, de la même façon que dans l'exemple
+précédent, à l'aide de la méthode `fold()`.
+
+Essayons maintenant de résoudre un problème un peu plus complexe en ajoutant les méthodes `zip()` et `map()`.
+Nous aimerions trouver quel est l'élément le plus petit en valeur absolue d'un vecteur donné.
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part10/src/find.rs:find_absolute_minimum}}
+```
+
+La première étape consiste à créer deux itérateurs. Le premier contient le signe de chaque élément
+et le deuxième, la valeur absolue de chaque élément.
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part10/src/find.rs:find_absolute_minimum_1}}
+```
+
+Pour obtenir ces itérateurs, nous allons transformer nos itérateurs obtenus avec `iter()` en utilsant
+la fonction `map()`. Cette méthode permet d'appliquer une même transformation sur tous les éléments
+d'un itérateur. Pour l'itérateur `signs`, on appelle la méthode `signum()` des `i32`, qui retourne 1 si
+le nombre est positif, 0 si le nombre est 0 et -1 si le nombre est négatif. Pour `abs_values`,
+nous utilisons la méthode `abs()` des `i32`, qui retourne la valeur absolue d'un nombre.
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part10/src/find.rs:find_absolute_minimum_2}}
+```
+
+Maintenant que nous avons nos deux itérateurs, nous aimerions pouvoir itérer sur les deux simultanément.
+Pour cela, nous pouvons utiliser la méthode `zip()`. Elle permet de transformer deux itérateurs, en un
+unique itérateur de tuple. Ici nous avons deux itérateurs de `i32`, qui deviennent donc un seul itérateur
+de type tuple `(i32, i32)`.
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part10/src/find.rs:find_absolute_minimum_3}}
+```
+
+Ensuite avec `fold()`, il nous suffit de comparer les valeurs absolues et de retourner une option contenant
+le signe et la valeur absolue.
+
+```rust,ignore
+{{#include ../../codes/rust_lang/part10/src/find.rs:find_absolute_minimum_4}}
+```
+
+Pour finir, on utilise la méthode `map()` de notre `Option<(i32,i32)>` pour multiplier
+la valeur absolue par le signe. Ce qui nous donne au final une `Option<i32>` contenant notre résultat.
+
+### Performances et lazy evaluation
+
+Les transformations sur les itérateurs sont en général aussi perfomantes qu'une
+simple boucle for. On peut voir par exemple [ce benchmark dans le livre Rust](https://doc.rust-lang.org/book/ch13-04-performance.html).
+Si on ajoute la possibilité de parallèliser facilement un code basé sur les itérateurs,
+leur intérêt paraît évident.
+
+Un des éléments qui explique les perfomances des itérateurs réside dans la lazy evaluation.
+Lorsqu'on appelle une opération de transformation sur un itérateur, la transformation n'est
+pas réalisée directement. C'est uniquement lorsqu'on appelle une fonction dite terminale, comme
+par exemple `fold()` ou `collect()` qui doivent produire un résulat. Les transformations intermédiaires
+peuvent ainsi souvent être fusionnés.
+
+Ce qui veut dire par exemple que dans le code suivant,
+
+```rust
+# fn main() {
+  let v = vec![0,1,2,3,4,5];
+  let it = v.iter().map(|x| x + 1).map(|x| x * 3).filter(|x| x % 2 == 1);
+  let res : Vec<i32> = it.collect();
+# }
+```
+
+que tant que la fonction `collect()` n'a pas été appelée, alors aucune transformation n'est effectuée.
+Si vous ne nous croyez pas, un moyen simple de vous en convaincre, consiste à appliquer
+une série de transformation sur un itérateur infini et de mesurer la performance.
+
+## Rustlings
+
+Les rustlings à faire dans ce chapitre sont les suivants:
+
+### Les itérateurs
+
+```bash
+$ rustlings run iterators1
+$ rustlings run iterators2
+$ rustlings run iterators3
+$ rustlings run iterators4
+$ rustlings run iterators5
+```
diff --git a/codes/rust_lang/part08/src/find.rs b/codes/rust_lang/part08/src/find.rs
index 0d61d8eca1d8b755ec5b99b6ffc7e631b4e963b3..c8dccdd94b6a885957468b2b62ed635d945259d1 100644
--- a/codes/rust_lang/part08/src/find.rs
+++ b/codes/rust_lang/part08/src/find.rs
@@ -6,8 +6,8 @@ use crate::binary_operator::BinaryOperator;
 
 /// Computes the result of a binary reduction of an Array of a type T.
 /// Take the binary operation as a function.
-/// Returns a [Option::Some] containing the the result value
-/// or [Option::None] if the array was empty value was found.
+/// Returns a [Option::Some] containing the result value
+/// or [Option::None] if the array was empty.
 ///
 /// # Example
 ///
diff --git a/codes/rust_lang/part10/Cargo.toml b/codes/rust_lang/part10/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..40bd900f032af074f2f57cab48d0709601a271d6
--- /dev/null
+++ b/codes/rust_lang/part10/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "part10"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/codes/rust_lang/part10/src/find.rs b/codes/rust_lang/part10/src/find.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8b0e6e3a5a6ebcd5c5df41063eb1d6a9a773d732
--- /dev/null
+++ b/codes/rust_lang/part10/src/find.rs
@@ -0,0 +1,109 @@
+//! Contains the core logic of the library, allowing to tore generic values
+//! (or their absence) and manipulate them.
+//! We demonstrates three kind of way to deal with errors
+
+/// Computes the minimum of a vector of i32.
+/// Returns a [Option::Some] containing the minimum value
+/// or [Option::None] if the vec was empty.
+///
+/// # Example
+///
+/// ```
+/// # use part10::find::{find_minimum};
+/// # fn main() {
+/// let v = vec![-2, 5, 18, 65, 22, 56, -30];
+/// let min = find_minimum(&v);
+/// assert!(min == Some(-30));
+/// # }
+/// ```
+// ANCHOR: find_minimum
+pub fn find_minimum(v: &Vec<i32>) -> Option<i32> {
+    v.iter().fold(None, |acc, current| {
+        let next_acc = if let Some(val) = acc {
+            if val <= *current {
+                val
+            } else {
+                *current
+            }
+        } else {
+            *current
+        };
+        Some(next_acc)
+    })
+}
+// ANCHOR_END: find_minimum
+
+/// Computes the smallest even number in a vector of i32.
+/// Returns a [Option::Some] containing the smallest even number
+/// or [Option::None] if the vec was empty.
+///
+/// # Example
+///
+/// ```
+/// # use part10::find::{find_even_minimum};
+/// # fn main() {
+/// let v = vec![15, 64, 47, 2, 1, 53, 22];
+/// let min = find_even_minimum(&v);
+/// assert!(min == Some(2));
+/// # }
+/// ```
+// ANCHOR: find_even_minimum
+pub fn find_even_minimum(v: &Vec<i32>) -> Option<i32> {
+    v.iter().filter(|i| *i % 2 == 0).fold(None, |acc, current| {
+        let next_acc = if let Some(val) = acc {
+            if val <= *current {
+                val
+            } else {
+                *current
+            }
+        } else {
+            *current
+        };
+        Some(next_acc)
+    })
+}
+// ANCHOR_END: find_even_minimum
+
+/// Computes the minimum absolute value of a vector of i32.
+/// Returns a [Option::Some] containing the minimum abs value
+/// or [Option::None] if the vec was empty.
+///
+/// # Example
+///
+/// ```
+/// # use part10::find::{find_absolute_minimum};
+/// # fn main() {
+/// let v = vec![-2, 5, 18, 65, 22, 56, -30];
+/// let min = find_absolute_minimum(&v);
+/// assert!(min == Some(-2));
+/// # }
+/// ```
+// ANCHOR: find_absolute_minimum
+pub fn find_absolute_minimum(v: &Vec<i32>) -> Option<i32> {
+    // ANCHOR: find_absolute_minimum_1
+    let signs = v.iter().map(|i| i.signum());
+    let abs_values = v.iter().map(|i| i.abs());
+    // ANCHOR_END: find_absolute_minimum_1
+    // ANCHOR: find_absolute_minimum_2
+    signs
+        .zip(abs_values)
+        // ANCHOR_END: find_absolute_minimum_2
+        // ANCHOR: find_absolute_minimum_3
+        .fold(None, |acc, (c_sign, c_abs_v)| {
+            let next_acc = if let Some((sign, abs_v)) = acc {
+                if abs_v <= c_abs_v {
+                    (sign, abs_v)
+                } else {
+                    (c_sign, c_abs_v)
+                }
+            } else {
+                (c_sign, c_abs_v)
+            };
+            Some(next_acc)
+        })
+        // ANCHOR_END: find_absolute_minimum_3
+        // ANCHOR: find_absolute_minimum_4
+        .map(|(sign, abs_v)| sign * abs_v)
+    // ANCHOR_END: find_absolute_minimum_4
+}
+// ANCHOR_END: find_absolute_minimum
diff --git a/codes/rust_lang/part10/src/io.rs b/codes/rust_lang/part10/src/io.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a0e2acf0fc5f99d49229b13275f542c12e4e1692
--- /dev/null
+++ b/codes/rust_lang/part10/src/io.rs
@@ -0,0 +1,23 @@
+//! Contains functions to interact with the user, either
+//! by reading inputs from the terminal, either by writing values
+//! in it.
+
+/// Poorly emulates the parsing of a command line.
+pub fn read_command_line_correct() -> Vec<i32> {
+    vec![-10, 32, 12, -43, 52, -53, 83, -2, 9]
+}
+
+/// Poorly emulates the parsing of a command line.
+pub fn read_empty_command_line() -> Vec<i32> {
+    vec![]
+}
+
+/// Prints all the elements of the vector.
+/// vector is borrowed here
+pub fn print_vec(v: &Vec<i32>) {
+    print!("[ ");
+    for t in v {
+        print!("{} ", t);
+    }
+    println!("]");
+}
diff --git a/codes/rust_lang/part10/src/lib.rs b/codes/rust_lang/part10/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..865bce85931b6656d9996d6624a971c796a41a60
--- /dev/null
+++ b/codes/rust_lang/part10/src/lib.rs
@@ -0,0 +1,28 @@
+//! This crate shows us different ways of dealing with errors in a Rust program.
+//! You will find examples of [Option], [Result] and [panic!].
+
+pub mod find;
+pub mod io;
+
+#[cfg(test)]
+mod tests {
+    use crate::find::{find_absolute_minimum, find_minimum};
+    const VEC: [i32; 9] = [10, 32, 12, 43, 52, 53, 83, 2, 9];
+    const VEC_2: [i32; 9] = [-10, 32, 12, -43, 52, -53, 83, -2, 9];
+    const MIN_VEC: i32 = 2;
+    const ABS_MIN_VEC_2: i32 = -2;
+
+    #[test]
+    fn test_find_minimum() {
+        let min: Option<i32> = find_minimum(&(VEC.to_vec()));
+
+        assert!(min == Some(MIN_VEC));
+    }
+
+    #[test]
+    fn test_find_absolute_minimum() {
+        let min: Option<i32> = find_absolute_minimum(&(VEC_2.to_vec()));
+
+        assert!(min == Some(ABS_MIN_VEC_2));
+    }
+}
diff --git a/codes/rust_lang/part10/src/main.rs b/codes/rust_lang/part10/src/main.rs
new file mode 100644
index 0000000000000000000000000000000000000000..33df24f1b266a2e676e2a4f2cedb516132ab5c51
--- /dev/null
+++ b/codes/rust_lang/part10/src/main.rs
@@ -0,0 +1,26 @@
+use part10::find::{find_absolute_minimum, find_even_minimum, find_minimum};
+use part10::io;
+
+fn main() {
+    let v = io::read_command_line_correct();
+    println!("Among the elements in the list:");
+    io::print_vec(&v);
+
+    let min = find_minimum(&v);
+    match min {
+        Some(val) => println!("The minimum value is {}", val),
+        None => eprintln!("There is no minimum"),
+    }
+
+    let min = find_absolute_minimum(&v);
+    match min {
+        Some(val) => println!("The minimum by absolue value is {}", val),
+        None => eprintln!("There is no minimum"),
+    }
+
+    let min = find_even_minimum(&v);
+    match min {
+        Some(val) => println!("The smallest even value is {}", val),
+        None => eprintln!("There is no minimum"),
+    }
+}
diff --git a/slides/src/SUMMARY.md b/slides/src/SUMMARY.md
index 399cd777d11ee1d780ecfcfb6d2c34402f7ef7ca..cb42373b38d60a3b066327813fa487299fe532cb 100644
--- a/slides/src/SUMMARY.md
+++ b/slides/src/SUMMARY.md
@@ -2,6 +2,7 @@
 
 - [Introduction](introduction.md)
 - [Installation](installation.md).
+- [Itérateurs](iterators.md).
 - [Variables](variables.md).
 - [Types](types.md).
 - [Structures de contrôle](control.md).
diff --git a/slides/src/iterators.md b/slides/src/iterators.md
new file mode 100644
index 0000000000000000000000000000000000000000..d7dadb2cc90ed204bfe2f4910b07f30b7cb0a833
--- /dev/null
+++ b/slides/src/iterators.md
@@ -0,0 +1,143 @@
+# Les itérateurs
+
+## Le trait itérateur
+
+Le trait itérateur d'après la documentation
+
+```rust
+trait Iterator {
+    type Item;
+    fn next(&mut self) -> Option<Self::Item>;
+}
+```
+
+## Les itérateurs infinis
+
+```rust[7-11|13-15]
+const fn my_random(s: i32) -> i32 {
+    // PRNG See wikipedia : https://en.wikipedia.org/wiki/Linear_congruential_generator
+    (((1664525i64 * s as i64) + 1013904223i64) % (1i64 << 32)) as i32
+}
+
+fn main() {
+    let mut seed: i32 = 123456;
+    let mut rand_iter = std::iter::from_fn(move || {
+        seed = my_random(seed);
+        Some(seed % 100)
+    });
+
+    println! {"{:?}", rand_iter.next()};
+    println! {"{:?}", rand_iter.next()};
+    println! {"{:?}", rand_iter.next()};
+}
+```
+
+## La fonction iter
+
+```rust[3-4|6-9]
+fn main()
+{
+    let v = vec![0, 1, 2];
+    let mut v_iter = v.iter();
+
+    println! {"{:?}", v_iter.next()};
+    println! {"{:?}", v_iter.next()};
+    println! {"{:?}", v_iter.next()};
+    println! {"{:?}", v_iter.next()};
+}
+```
+
+## La fonction collect
+
+```rust[7-11|13|14]
+const fn my_random(s: i32) -> i32 {
+    // PRNG See wikipedia : https://en.wikipedia.org/wiki/Linear_congruential_generator
+    (((1664525i64 * s as i64) + 1013904223i64) % (1i64 << 32)) as i32
+}
+
+fn main() {
+    let mut seed: i32 = 123456;
+    let mut rand_iter = std::iter::from_fn(move || {
+        seed = my_random(seed);
+        Some(seed % 100)
+    });
+
+    let v_rand: Vec<i32> = rand_iter.take(5).collect();
+    println!("{:?}", v_rand);
+}
+```
+- La fonction `take(5)` crée un nouvel itérateur de 5 éléments. 
+
+## `map()`
+
+```rust[5|]
+fn main()
+{
+    let v = vec![0, 1, 2];
+    let v_res: Vec<i32> = v.iter()
+                           .map(|x| x + 1)
+                           .collect();
+
+    println! {"{:?}", v_res};
+}
+```
+
+## `filter()`
+
+```rust[6|]
+fn main()
+{
+    let v = vec![0, 1, 2];
+    let v_res: Vec<i32> = v.iter()
+                           .map(|x| x + 1)
+                           .filter(|x| x % 2 == 1)
+                           .collect();
+
+    println! {"{:?}", v_res};
+}
+```
+
+## Rappel élément neutre
+
+L'élément neutre `N` d'une opération `★` est l'élément tel que `N ★ x = x ★ N = x` pour tout `x`.
+
+- Exemple : 0 pour l'addition, car `0 + x = x + 0 = x`
+- Exemple : 1 pour la multiplication, car `1 * x = x * 1 = x`
+
+## `fold()`
+
+```rust[8|4|]
+fn main()
+{
+    let v = vec![0, 1, 2];
+    let sum: i32 = v
+        .iter()
+        .map(|x| x + 1)
+        .filter(|x| x % 2 == 1)
+        .fold(0, |acc, current| acc + current);
+
+    println! {"{:?}", sum};
+}
+```
+
+## `zip()`
+
+```rust[6-8|9-11|]
+fn main()
+{
+    let chiffres = vec![1, 2, 3, 4];
+    let lettres = vec!['a', 'b', 'c', 'd'];
+
+    chiffres
+        .iter()
+        .zip(lettres.iter())
+        .for_each(
+            |(chiffre, lettre)| println!("{lettre} est la lettre n°{chiffre} de l'alphabet",),
+        );
+}
+```
+
+## Lazy evaluation et performances
+
+- La performance des itérateurs est comparable aux boucles
+- Les transformations sont appliquées uniquement lorsque que l'on veut récupérer une valeur. On appelle ça **lazy evaluation**