Adloun

informatique (MP2I/MPI) · Chapitre 2 · Application directe du cours

Masquer n'est pas modifier

Le langage OCaml · niveau 2

É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 = 20 ne modifie rien : il crée une seconde liaison, qui masque la première pour tout ce qui vient après. La fonction lire_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 second let, voit .
  • b := 20 modifie le contenu d'une case, sans toucher à la liaison. lire_b avait 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.

Exercices semblables

Le cours du chapitre · Tous les exercices du chapitre