Masquer n'est pas modifier
Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 2 — Le langage OCaml
Énoncé
Que produit ce programme ? Expliquer les trois lignes affichées.
let a = 10
let lire_a () = a
let a = 20
let b = ref 10
let lire_b () = !b
let () = b := 20
let () =
print_int (lire_a ()); print_newline ();
print_int a; print_newline ();
print_int (lire_b ()); print_newline ()Corrigé
Il affiche 10, puis 20, puis 20.
Deux mécanismes différents, et c'est tout le sujet.
let a = 20ne modifie rien : il crée une seconde liaison, qui masque la première pour tout ce qui vient après. La fonctionlire_a, elle, a été définie avant, et la portée lexicale fixe alors ce qu'elle voit — « c'est la valeur de cette variable au moment de la définition qui est prise en compte », dit l'annexe. Elle rend donc , définitivement. La troisième ligne du programme, écrite après le secondlet, voit .b := 20modifie le contenu d'une case, sans toucher à la liaison.lire_bavait capturé la case, pas son contenu : elle voit donc la nouvelle valeur.
Le piège, et sa forme générale. On croit avoir deux fois le même phénomène parce que l'écriture se ressemble. Elle ne se ressemble que typographiquement : let x = e lie, r := e écrit. La question à se poser devant un let qui reprend un nom existant est toujours : « qui a été défini avant ? ». Ce que la première ligne montre serait, en C, un comportement impossible — une variable globale y est une case, et toute fonction voit sa dernière valeur.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.