diff --git a/README.md b/README.md
index 057f53c866f0a80decdb110579007babe6aa9b91..df455d1b19c2e1998dd08cc68cfdd8cf43205bfc 100644
--- a/README.md
+++ b/README.md
@@ -6,28 +6,28 @@
 - [Rappels git et gitlab](gitlab.md)
 - [Questions sur le cours](https://forge.univ-lyon1.fr/programmation-fonctionnelle/lifpf/-/issues/?sort=updated_desc&state=all&label_name%5B%5D=Question)
 
-| jour  | heure         | type          | supports / remarques                                                                      |
-| ----- | ------------- | ------------- | ----------------------------------------------------------------------------------------- |
-| 16/01 | 8h            | CM            | [Diapositives](cm/lifpf-cm1.pdf)                                                          |
-|       | 9h45          | TD            | [Sujet](td/lifpf-td1-enonce.pdf), [corrigé](td/lifpf-td1-correction.pdf)                  |
-| 23/01 | 8h            | CM            | [Diapositives](cm/lifpf-cm2.pdf), [Script démos](cm/cm2-demo.md)                          |
-|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp1.md), [corrigé](tp/tp1.ml) <br> Groupe de TP, horaire et salle sur [tomuss] |
-| 30/01 | 8h            | TD + QCM      | [Sujet](td/lifpf-td2-enonce.pdf), [corrigé](td/lifpf-td2-correction.pdf)                  |
-|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp2.md), [corrigé](tp/tp2.ml) <br> Groupe de TP, horaire et salle sur [tomuss] |
-| 20/02 | 8h            | CM            | [Diapositives](cm/lifpf-cm3.pdf)                                                          |
-|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp3.md), [corrigé](tp/tp3.ml)                                                  |
-| 27/02 | 8h            | TD + QCM      | [Sujet](td/lifpf-td3-enonce.pdf), [corrigé](td/lifpf-td3-correction.pdf)                  |
-|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp4.md), [corrigé](tp/tp4.ml)                                                  |
-| 06/03 | 8h            | CM            | [Diapositives](cm/lifpf-cm4.pdf)                                                          |
-|       | 9h45          | TD + QCM      | [Sujet](td/lifpf-td4-enonce.pdf), [corrigé](td/lifpf-td4-correction.pdf)                  |
-| 13/03 | 8h            | CM            | [Diapositives](cm/lifpf-cm5.pdf)                                                          |
-|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp5.md), [corrigé de l'exercice 1](tp/tp5.ml)                                  |
-| 20/03 | 8h            | TD + QCM      | [Sujet](td/lifpf-td5-enonce.pdf), [corrigé](td/lifpf-td5-correction.pdf)                  |
-|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp6.md), corrigés dans les TD/TPs référencés dans le sujet                     |
-| 27/03 | 9h45 ou 11h15 | TP            | [Sujet](tp/tp7.md), [corrigé](tp/tp7.zip)                                                 |
-| 03/04 | 8h            | CM            | [Diapositives](cm/lifpf-cm6.pdf), [code](cm/cm6-code.ml)                                  |
-|       | 9h45          | TD + Contrôle | [Sujet](td/lifpf-td6-enonce.pdf)                                                          |
-| 24/04 | 9h45 ou 11h15 | TP            | [Sujet](tp/tp8.md) <br> Horaires et groupes sur [tomuss]                                  |
+| jour  | heure         | type          | supports / remarques                                                                                           |
+| ----- | ------------- | ------------- | -------------------------------------------------------------------------------------------------------------- |
+| 16/01 | 8h            | CM            | [Diapositives](cm/lifpf-cm1.pdf)                                                                               |
+|       | 9h45          | TD            | [Sujet](td/lifpf-td1-enonce.pdf), [corrigé](td/lifpf-td1-correction.pdf)                                       |
+| 23/01 | 8h            | CM            | [Diapositives](cm/lifpf-cm2.pdf), [Script démos](cm/cm2-demo.md)                                               |
+|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp1.md), [corrigé](tp/tp1.ml)                                                                       |
+| 30/01 | 8h            | TD + QCM      | [Sujet](td/lifpf-td2-enonce.pdf), [corrigé](td/lifpf-td2-correction.pdf)                                       |
+|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp2.md), [corrigé](tp/tp2.ml)                                                                       |
+| 20/02 | 8h            | CM            | [Diapositives](cm/lifpf-cm3.pdf)                                                                               |
+|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp3.md), [corrigé](tp/tp3.ml)                                                                       |
+| 27/02 | 8h            | TD + QCM      | [Sujet](td/lifpf-td3-enonce.pdf), [corrigé](td/lifpf-td3-correction.pdf)                                       |
+|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp4.md), [corrigé](tp/tp4.ml)                                                                       |
+| 06/03 | 8h            | CM            | [Diapositives](cm/lifpf-cm4.pdf)                                                                               |
+|       | 9h45          | TD + QCM      | [Sujet](td/lifpf-td4-enonce.pdf), [corrigé](td/lifpf-td4-correction.pdf)                                       |
+| 13/03 | 8h            | CM            | [Diapositives](cm/lifpf-cm5.pdf)                                                                               |
+|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp5.md), [corrigé de l'exercice 1](tp/tp5.ml)                                                       |
+| 20/03 | 8h            | TD + QCM      | [Sujet](td/lifpf-td5-enonce.pdf), [corrigé](td/lifpf-td5-correction.pdf)                                       |
+|       | 9h45 ou 11h30 | TP            | [Sujet](tp/tp6.md), corrigés dans les TD/TPs référencés dans le sujet                                          |
+| 27/03 | 9h45 ou 11h15 | TP            | [Sujet](tp/tp7.md), [corrigé](tp/tp7.zip)                                                                      |
+| 03/04 | 8h            | CM            | [Diapositives](cm/lifpf-cm6.pdf), [code](cm/cm6-code.ml)                                                       |
+|       | 9h45          | TD + Contrôle | [Sujet](td/lifpf-td6-enonce.pdf)                                                                               |
+| 24/04 | 9h45 ou 11h15 | TP            | [Sujet](tp/tp8.md), corrigé calculette programmable: [sans](tp/tp8.ml) ou [avec](tp/tp8b.ml) fonctions natives |
 
 ### Évaluation
 
diff --git a/tp/tp8.ml b/tp/tp8.ml
new file mode 100644
index 0000000000000000000000000000000000000000..6a155a73f2f37a08a44af993cfb7376d03af2d13
--- /dev/null
+++ b/tp/tp8.ml
@@ -0,0 +1,126 @@
+(**********************************************************************)
+(* Calculatrice programmable *)
+(**********************************************************************)
+
+(**
+Type représentant les opérateurs binaires.    
+*)
+type binop = Plus | Moins | Mult | Div
+
+(**
+Expressions arithmétiques + let + fun + app 
+*)
+type expr =
+  | Cst of int
+  | Binop of binop * expr * expr
+  | Var of string
+  | Let of string * expr * expr
+  | Fun of string * expr
+  | App of expr * expr
+
+(** affichage **)
+let rec string_of_expr (e : expr) : string =
+  let string_of_binop (b : binop) =
+    match b with
+    | Plus -> " + "
+    | Moins -> " - "
+    | Mult -> " * "
+    | Div -> " / "
+  in
+
+  match e with
+  | Cst n -> string_of_int n
+  | Binop (op, l, r) ->
+      "(" ^ string_of_expr l ^ string_of_binop op
+      ^ string_of_expr r ^ ")"
+  | Var x -> x
+  | Let (v, e1, e2) ->
+      "(let " ^ v ^ " = " ^ string_of_expr e1 ^ " in "
+      ^ string_of_expr e2 ^ ")"
+  | Fun (x, e) -> "(fun " ^ x ^ " -> " ^ string_of_expr e ^ ")"
+  | App (e1, e2) ->
+      "(" ^ string_of_expr e1 ^ " " ^ string_of_expr e2 ^ ")"
+
+(** Erreurs *)
+type eval_err = DivZero | VarNonDef | PasUneFonction | PasUnInt
+
+(** Résultats: int ou erreur ou fermeture*)
+type resultat =
+  | Int of int
+  | Err of eval_err
+  | Fermeture of string * expr * (string * resultat) list
+
+(**
+Évalue une expression dans un environnement
+*)
+let rec eval_expr (e : expr) (env : (string * resultat) list) :
+    resultat =
+  match e with
+  | Cst n -> Int n
+  | Binop (op, e1, e2) -> (
+      match (eval_expr e1 env, eval_expr e2 env) with
+      | Int v1, Int v2 -> (
+          match op with
+          | Plus -> Int (v1 + v2)
+          | Moins -> Int (v1 - v2)
+          | Mult -> Int (v1 * v2)
+          | Div -> if v2 = 0 then Err DivZero else Int (v1 / v2))
+      | Fermeture _, _ -> Err PasUnInt
+      | _, Fermeture _ -> Err PasUnInt
+      | Err e, _ -> Err e
+      | _, Err e -> Err e)
+  | Var x -> (
+      match List.assoc_opt x env with
+      | None -> Err VarNonDef
+      | Some r -> r)
+  | Let (x, e1, e2) -> (
+      match eval_expr e1 env with
+      | Err e -> Err e
+      | v1 -> eval_expr e2 ((x, v1) :: env))
+  | Fun (x, e) -> Fermeture (x, e, env)
+  | App (f, a) -> (
+      match eval_expr f env with
+      | Err e -> Err e
+      | Int _ -> Err PasUneFonction
+      | Fermeture (x, e, env_f) -> (
+          match eval_expr a env with
+          | Err e -> Err e
+          | v -> eval_expr e ((x, v) :: env_f)))
+
+let e1 = Cst 3
+let e2 = Binop (Plus, Cst 3, Cst 5)
+let e3 = Binop (Div, Cst 3, Cst 0)
+let e4 = Let ("a", Cst 3, Binop (Moins, Var "a", Cst 3))
+let e5 = Let ("a", Cst 3, Var "b")
+
+let e6 =
+  Let
+    ( "f1",
+      Fun ("x", Binop (Plus, Var "x", Cst 3)),
+      Let
+        ( "f2",
+          Fun ("y", Binop (Mult, App (Var "f1", Var "y"), Cst 5)),
+          App (Var "f2", Cst 2) ) )
+
+let e7 =
+  Let
+    ( "f",
+      Fun
+        ( "x",
+          Fun
+            ( "y",
+              Binop (Mult, Var "x", Binop (Plus, Var "y", Cst 3))
+            ) ),
+      App (App (Var "f", Cst 5), Cst 3) )
+;;
+
+assert (eval_expr e1 [] = Int 3);;
+assert (eval_expr e2 [] = Int 8);;
+assert (eval_expr e3 [] = Err DivZero);;
+assert (eval_expr e4 [] = Int 0);;
+assert (eval_expr e5 [] = Err VarNonDef);;
+assert (eval_expr e5 [ ("b", Int 11) ] = Int 11);;
+assert (eval_expr e6 [] = Int 25);;
+assert (eval_expr e7 [] = Int 30)
+
+(**********************************************************************)
diff --git a/tp/tp8b.ml b/tp/tp8b.ml
new file mode 100644
index 0000000000000000000000000000000000000000..571433baa06f64927deb3642313191b58bbdae2a
--- /dev/null
+++ b/tp/tp8b.ml
@@ -0,0 +1,127 @@
+(**********************************************************************)
+(* Calculatrice programmable, pour aller plus loin *)
+(**********************************************************************)
+
+(**
+Expressions arithmétiques + let + fun + app 
+*)
+type expr =
+  | Cst of int
+  | Var of string
+  | Let of string * expr * expr
+  | Fun of string * expr
+  | App of expr * expr
+
+(** affichage **)
+let rec string_of_expr (e : expr) : string =
+  match e with
+  | Cst n -> string_of_int n
+  | Var x -> x
+  | Let (v, e1, e2) ->
+      "(let " ^ v ^ " = " ^ string_of_expr e1 ^ " in "
+      ^ string_of_expr e2 ^ ")"
+  | Fun (x, e) -> "(fun " ^ x ^ " -> " ^ string_of_expr e ^ ")"
+  | App (e1, e2) ->
+      "(" ^ string_of_expr e1 ^ " " ^ string_of_expr e2 ^ ")"
+
+(** Erreurs *)
+type eval_err = DivZero | VarNonDef | PasUneFonction | PasUnInt
+
+(** Résultats: int ou erreur ou fermeture*)
+type resultat =
+  | Int of int
+  | Err of eval_err
+  | Fermeture of string * expr * (string * resultat) list
+  | Native of (resultat -> resultat)
+
+(**
+Évalue une expression dans un environnement
+*)
+let rec eval_expr (e : expr) (env : (string * resultat) list) :
+    resultat =
+  match e with
+  | Cst n -> Int n
+  | Var x -> (
+      match List.assoc_opt x env with
+      | None -> Err VarNonDef
+      | Some r -> r)
+  | Let (x, e1, e2) -> (
+      match eval_expr e1 env with
+      | Err e -> Err e
+      | v1 -> eval_expr e2 ((x, v1) :: env))
+  | Fun (x, e) -> Fermeture (x, e, env)
+  | App (f, a) -> (
+      match eval_expr f env with
+      | Err e -> Err e
+      | Int _ -> Err PasUneFonction
+      | Fermeture (x, e, env_f) -> (
+          match eval_expr a env with
+          | Err e -> Err e
+          | v -> eval_expr e ((x, v) :: env_f))
+      | Native f -> f (eval_expr a env))
+
+let native_binop_res (f : int -> int -> resultat) : resultat =
+  Native
+    (fun (a : resultat) ->
+      Native
+        (fun (b : resultat) ->
+          match (a, b) with
+          | Err e, _ -> Err e
+          | _, Err e -> Err e
+          | Int va, Int vb -> f va vb
+          | _, _ -> Err PasUnInt))
+
+let native_binop (f : int -> int -> int) : resultat =
+  native_binop_res (fun a b -> Int (f a b))
+
+let builtins =
+  [
+    ("+", native_binop ( + ));
+    ("-", native_binop ( - ));
+    ("*", native_binop ( * ));
+    ( "/",
+      native_binop_res (fun x y ->
+          if y = 0 then Err DivZero else Int (x / y)) );
+  ]
+
+let e1 = Cst 3
+let e2 = App (App (Var "+", Cst 3), Cst 5)
+let e3 = App (App (Var "/", Cst 3), Cst 0)
+let e4 = Let ("a", Cst 3, App (App (Var "-", Var "a"), Cst 3))
+let e5 = Let ("a", Cst 3, Var "b")
+
+let e6 =
+  Let
+    ( "f1",
+      Fun ("x", App (App (Var "+", Var "x"), Cst 3)),
+      Let
+        ( "f2",
+          Fun
+            ( "y",
+              App (App (Var "*", App (Var "f1", Var "y")), Cst 5)
+            ),
+          App (Var "f2", Cst 2) ) )
+
+let e7 =
+  Let
+    ( "f",
+      Fun
+        ( "x",
+          Fun
+            ( "y",
+              App
+                ( App (Var "*", Var "x"),
+                  App (App (Var "+", Var "y"), Cst 3) ) ) ),
+      App (App (Var "f", Cst 5), Cst 3) )
+;;
+
+assert (eval_expr e1 builtins = Int 3);;
+assert (eval_expr e2 builtins = Int 8);;
+assert (eval_expr e3 builtins = Err DivZero);;
+assert (eval_expr e4 builtins = Int 0);;
+assert (eval_expr e5 builtins = Err VarNonDef);;
+assert (eval_expr e5 (("b", Int 11) :: builtins) = Int 11);;
+assert (eval_expr e6 builtins = Int 25);;
+assert (eval_expr e7 builtins = Int 30)
+
+(**********************************************************************)