On souhaite maintenant utiliser une fonction pour condenser le code suivant :
let nb_colonnes = read_int() in if nb_colonnes > 5 then begin for colonne = 1 to nb_colonnes do print_string "-"; done; end else begin for colonne = 1 to nb_colonnes do print_string "."; done; end ;
Le code qu'on peut mettre en commun, qui correspond au corps de la fonction, est de la forme :
for colonne = 1 to nb_colonnes do print_string motif; done;
On va nommer cette fonction affiche_nb_fois
. Son paramètre est motif
. Voici la déclaration de la fonction affiche_nb_fois
:
let affiche_nb_fois motif = for colonne = 1 to nb_colonnes do print_string motif; done; in
Pour utiliser cette fonction, on fera affiche_nb_fois "-"
dans le bloc du then
, et affiche_nb_fois "."
dans le bloc du else
. On aura donc :
if nb_colonnes > 5 then begin affiche_nb_fois "-"; end else begin affiche_nb_fois "."; end ;
qui se simplifie (attention aux point-virgules) par la réduction des blocs en :
if nb_colonnes > 5 then affiche_nb_fois "-" else affiche_nb_fois ".";
Pour que le programme fonctionne, il faut précéder ce code de la déclaration de nb_colonnes
et la déclaration de la fonction :
let nb_colonnes = read_int() in let affiche_nb_fois motif = for colonne = 1 to nb_colonnes do print_string motif; done; in if nb_colonnes > 5 then affiche_nb_fois "-" else affiche_nb_fois ".";
Et voilà, ça marche !
Expliquez maintenant pourquoi le code suivant le compile pas :
let affiche_nb_fois motif = for colonne = 1 to nb_colonnes do print_string motif; done; in let nb_colonnes = read_int() in if nb_colonnes > 5 then affiche_nb_fois "-" else affiche_nb_fois ".";
Regardons l'erreur de compilation :
File "test.ml", line 2, characters 22-33: Unbound value nb_colonnes
La fonction affiche_nb_fois
utilise la valeur de nb_colonnes
, et par conséquent le compilateur oblige le programmeur à définir la valeur de nb_colonnes
avant de déclarer la fonction qui l'utilise. Cela évite d'avoir des situations avec des comportements indéterminés.
Voyons une variante du code du début. Le programme demande un premier motif à l'utilisateur, et affiche ce motif 10 fois de suite. Ensuite il demande un second motif à l'utilisateur, et l'affiche 15 fois de suite. Voici le code :
let motif_1 = read_line() in for colonne = 1 to 10 do print_string motif_1; done; print_newline(); let motif_2 = read_line() in for colonne = 1 to 15 do print_string motif_2; done;
Voyez-vous quelle fonction on pourrait utiliser pour condenser ce code ? Cherchez un peu avant de lire la suite. Indication : il faut mettre le read_line()
à l'intérieur du corps de la fonction.
Le motif répété est :
let motif = read_line() in for colonne = 1 to nb_colonnes do print_string motif; done;
La fonction, que l'on appelle affiche_nb_motifs_choisi
, prend en paramètre nb_colonnes
. Voici donc le code :
let affiche_nb_motifs_choisi nb_colonnes = let motif = read_line() in for colonne = 1 to nb_colonnes do print_string motif; done; in affiche_nb_motifs_choisi 10; print_newline(); affiche_nb_motifs_choisi 15;