diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2cb69b4ab02eec99607328a0280f843fd4ca4f95..6f0fb81a2cb396a609b103a6ace8b12632afbe57 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -19,4 +19,5 @@ run_test_doc:
     - cd codes
     - ./run_tests.sh
     - cd ../book
+    - mdbook test
     - mdbook build
diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md
index 99b1e890d5924a70d36a9347c3ed2e9dd709433d..a5ffa5285f7e95ae9e534065fe1ddb9152eee0bf 100644
--- a/book/src/SUMMARY.md
+++ b/book/src/SUMMARY.md
@@ -1,3 +1,4 @@
 # Summary
 
 - [Part 00](./part00.md)
+- [Part 01](./part01.md)
diff --git a/book/src/part01.md b/book/src/part01.md
new file mode 100644
index 0000000000000000000000000000000000000000..ca4c6af53b0f0fe6cfb18c4b7aa1afbeb79aa805
--- /dev/null
+++ b/book/src/part01.md
@@ -0,0 +1,255 @@
+# Discussion du code `part01`
+
+## Concepts
+
+Les concepts abordés dans cet exemple sont:
+
+1. [Les fonctions.](#les-fonctions)
+2. [Les `if ... else` sont des **expressions**.](#en-rust-le-if-est-une-expression)
+3. [Itérer sur les éléments d'un tableaux directement avec la boucle for.](#la-boucle-for-revisitée)
+
+## Discussion
+
+### Les fonctions
+
+Dans cette seconde itération de notre programme calculant le minimum d'une liste de nombres,
+nous introduisons les **fonctions** en Rust.
+
+La syntaxe d'une fonction est la suivante:
+```rust,ignore
+fn function_name(arg1: type, arg2: type, ...) -> ReturnType
+```
+Une fonction est annotée avec le mot-clé `fn` suivi de son identifiant. 
+Son type de retour se trouve à droite après la *flèche* (en ASCII-art) `->`.
+Si une fonction n'a pas de type de retour explicite (il n'y a pas de flèche) le type de retour est `()` qui
+rappelle le type `void` de C (aka sans type, mais oui c'est un type en Rust). Entre parenthèses se trouvent les arguments de la fonction suivi de leur type. Le nombre d'arguments est supérieur ou égal à zéro.
+
+Une fonction est ensuite appelée par son identifiant et ses éventuels arguments.
+
+```rust,no_run
+const SIZE: usize = 9;
+fn read_command_line() -> [i32; SIZE] {
+    [10, 32, 12, 43, 52, 53, 83, 2, 9]
+    // équivalent à return [10, 32, 12, 43, 52, 53, 83, 2, 9];
+}
+fn main() {
+    read_command_line();
+}
+```
+La fonction `read_command_line()` ne prend ainsi aucun argument et retourne un tableau statique d'entier 32 bits et de taille `SIZE`.
+Pour qu'une fonction retourne une valeur, on a deux solutions:
+1. Si la valeur est la dernière expression de la fonction, on peut juste mettre la valeur (ou la variable) sans point virgule à la fin de la ligne.
+2. On peut, de façon similaire au C, utiliser le mot clé `return val;`
+On constate ici que les tableaux statiques (contrairement à ce qui se passe dans le langage C) peuvent être retournés
+par une fonction (le tableau n'est pas désalloué au moment du retour).
+
+La vérification de la taille du tableau se fait dans la fonction `check_size(size: usize)` qui prend donc un argument de
+type `usize` et ne retourne rien.
+
+```rust,should_panic
+fn check_size(size: usize) {
+    # if size == 0 {
+    #     panic!("Size is of tab = 0.");
+    # }
+}
+# fn main() {
+check_size(10); // runs alright
+check_size(0);  // panics
+# }
+```
+
+À l'inverse la fonction `print_tab(tab)` prend en argument un tableau statique et ne retourne rien.
+
+```rust
+# const SIZE: usize = 9;
+# fn read_command_line() -> [i32; SIZE] {
+#     [10, 32, 12, 43, 52, 53, 83, 2, 9]
+# }
+fn print_tab(tab: [i32; SIZE]) {
+    for t in tab {
+        print!("{} ", t);
+    }
+    println!();
+}
+# fn main() {
+let tab = read_command_line();
+print_tab(tab);
+# }
+```
+
+Les fonctions `min_i32(lhs, rhs)` retourne la plus petite valeur de deux entiers signés de 32 bits.
+
+```rust
+fn min_i32(lhs: i32, rhs: i32) -> i32 {
+    if lhs < rhs {
+        lhs
+    } else {
+        rhs
+    }
+}
+# fn main() {
+let min = min_i32(2, 10);
+println!("{min}");    
+# }
+```
+
+### En Rust le `if` est une expression
+
+Mais si vous étudiez attentivement ce code, on constate que le corps de la fonction est étrange.
+On voit qu'aucune ligne ne possède de point terminal. Cela voudrait dire que `lhs` ou `rhs` sont la dernière expression
+de la fonction. En fait ce qui se passe c'est que le `if ... else` est une **expression**. De façon similaire au
+`if` ternaire en `C`, le `if ... else` en Rust retourne une valeur. On peut écrire de façon équivalente au code ci-dessus
+```rust
+fn min_i32(lhs: i32, rhs: i32) -> i32 {
+    let min = if lhs < rhs {
+        lhs
+    } else {
+        rhs
+    };
+    min
+}
+# fn main() {
+let min = min_i32(2, 10);
+println!("{min}");    
+# }
+```
+On voit qu'ici à la fin du bloc du `else` nous avons un point virgule qui indique la fin de la ligne.
+Ainsi `lhs` ou `rhs` sont liés à la variable immutable `min`.
+
+Cette notion d'expression est très importante. Comme nous l'avons expliqué précédemment la dernière expression d'une fonction est évaluée puis retournée par cette dernière.
+
+Un bloc de code qui produit un résultat est une expression.
+
+En Rust, plusieurs structures de contrôle tel que le `If` sont des expression. Il n'est pas nécessaire de connaître la valeur de l'expression pour la retourner.
+
+Nous pourrions considérer par exemple les fonctions suivante :
+
+```rust,no_run
+fn add(lhs: i32, rhs: i32) -> i32 {
+    lhs + rhs
+}
+
+fn add_one(val: i32) -> i32 {
+    add(1, val)
+}
+```
+### La boucle `for` revisitée
+
+La dernière fonction à discuter est `find_min(tab)` qui retourne la valeur minimale se trouvant dans `tab`.
+
+```rust
+# const SIZE: usize = 9;
+# fn read_command_line() -> [i32; SIZE] {
+#     [10, 32, 12, 43, 52, 53, 83, 2, 9]
+# }
+# fn check_size(size: usize) {
+#     if size == 0 {
+#         panic!("Size is of tab = 0.");
+#     }
+# }
+# fn min_i32(lhs: i32, rhs: i32) -> i32 {
+#     if lhs < rhs {
+#         lhs
+#     } else {
+#         rhs
+#     }
+# }
+fn find_min(tab: [i32; SIZE]) -> i32 {
+    check_size(SIZE);
+    let mut min = i32::MAX;
+    for t in tab {
+        min = min_i32(min, t);
+    }
+    min
+}
+# fn main() {
+let min = find_min(read_command_line());
+println!("The minimal value is: {min}");
+# }
+```
+Cette version du calcul du minimum contient une différence importante dans la syntaxe de la boucle `for`.
+En effet, ici on itère pas sur un indice et on accède ensuite aux éléments du tableau.
+La syntaxe
+```rust,ignore
+for val in tab
+```
+permet d'itérer directement sur les valeurs contenues dans `tab`. Au début de chaque tour de la boucle `for`,
+val prend la valeur "courante" du tableau. A la fin du bloc du `for`, la valeur courante prend la valeur "suivante"
+dans le tableau si elle existe. En fait le tableau est implicitement converti en *itérateur* (plus de détails plus tard sur le sujet).
+
+Dans d'autres langages on appelle ça une boucle "for each" qui traduit en français signifie *pour chaque*. 
+
+Le code ci-dessus est strictement équivalent à
+
+```rust
+# const SIZE: usize = 9;
+# fn read_command_line() -> [i32; SIZE] {
+#     [10, 32, 12, 43, 52, 53, 83, 2, 9]
+# }
+# fn check_size(size: usize) {
+#     if size == 0 {
+#         panic!("Size is of tab = 0.");
+#     }
+# }
+# fn min_i32(lhs: i32, rhs: i32) -> i32 {
+#     if lhs < rhs {
+#         lhs
+#     } else {
+#         rhs
+#     }
+# }
+fn find_min(tab: [i32; SIZE]) -> i32 {
+    check_size(SIZE);
+    let mut min = i32::MAX;
+    for i in 0..SIZE {
+        min = min_i32(min, tab[i]);
+    }
+    min
+}
+# fn main() {
+let min = find_min(read_command_line());
+println!("The minimal value is: {min}");
+# }
+```
+
+## Le code
+
+```rust
+# const SIZE: usize = 9;
+# fn read_command_line() -> [i32; SIZE] {
+#     [10, 32, 12, 43, 52, 53, 83, 2, 9]
+# }
+# fn check_size(size: usize) {
+#     if size == 0 {
+#         panic!("Size is of tab = 0.");
+#     }
+# }
+# fn print_tab(tab: [i32; SIZE]) {
+#     for t in tab {
+#         print!("{} ", t);
+#     }
+#     println!();
+# }
+# fn min_i32(lhs: i32, rhs: i32) -> i32 {
+#     if lhs < rhs {
+#         lhs
+#     } else {
+#         rhs
+#     }
+# }
+# fn find_min(tab: [i32; SIZE]) -> i32 {
+#     check_size(SIZE);
+#     let mut min = i32::MAX;
+#     for t in tab {
+#         min = min_i32(min, t);
+#     }
+#     min
+# }
+fn main() {
+    let tab = read_command_line();
+    println!("Among the numbers in the list:");
+    print_tab(tab);
+    let min = find_min(tab);
+    println!("The minimal value is: {min}");
+}
+```
diff --git a/codes/rust_lang/part01/src/main.rs b/codes/rust_lang/part01/src/main.rs
index 44065235cad65b8b64c5d1418ed21233ec2e7ffa..832223edf08d207d22b6abcc2cfeb86cd9f78eb9 100644
--- a/codes/rust_lang/part01/src/main.rs
+++ b/codes/rust_lang/part01/src/main.rs
@@ -3,8 +3,6 @@
 ///     - Arguments are "moved"
 ///     - if is an expression
 ///     - for loops revisited
-///     - Tuples
-///     - Destructuring
 
 const SIZE: usize = 9;
 
@@ -21,12 +19,11 @@ fn check_size(size: usize) {
 
 // Prints tab and returns tab.
 // Tab would be destructed at the end of the function otherwise.
-fn print_tab(tab: [i32; SIZE]) -> [i32; SIZE] {
+fn print_tab(tab: [i32; SIZE]) {
     for t in tab {
         print!("{} ", t);
     }
     println!();
-    tab
 }
 
 fn min_i32(lhs: i32, rhs: i32) -> i32 {
@@ -37,23 +34,19 @@ fn min_i32(lhs: i32, rhs: i32) -> i32 {
     }
 }
 
-fn find_min(tab: [i32; SIZE], size: usize) -> ([i32; SIZE], i32) {
-    check_size(size);
+fn find_min(tab: [i32; SIZE]) -> i32 {
+    check_size(SIZE);
     let mut min = i32::MAX;
     for t in tab {
         min = min_i32(min, t);
     }
-    (tab, min)
+    min
 }
 
 fn main() {
     let tab = read_command_line();
-
     println!("Among the numbers in the list:");
-    let tab = print_tab(tab);
-
-    // There are alternatives to access fields of tuples
-    let (_, min) = find_min(tab, SIZE);
-    // The first field is not used therefore we can replace it with "_"
+    print_tab(tab);
+    let min = find_min(tab);
     println!("The minimal value is: {}", min);
 }