Pour appeler une fonction favec un argument x, on écrit simplement f x. Vous pouvez aussi écrire (f x),
(f)x,f(x) ou (f)((x)) si cela vous fait plaisir, mais contrairement à la notation mathématique, les paren-
thèses autour du xne sont pas nécessaires, et je vous déconseille de les mettre.
Le problème de la notation mathématique est son extension aux appels de fonction à plusieurs arguments,
comme par exemple g x y : on donne à la fonction gl’argument x, puis y. Si l’on veut être précis, on dit
que l’application de xàgrenvoie une fonction (gest de la forme fun a -> fun b -> c), et que c’est à cette
fonction qu’on applique y. On pourrait donc aussi écrire let h = g x in h y ou (g x) y.
C’est ici que la notation mathématique à laquelle vous êtes habitués risque de vous faire faire des erreurs.
g x y est équivalent à (g x) y, mais pas àg(x y) ! Cette deuxième écriture signifie qu’on applique yàx, et
qu’on donne le résultat à g. Par contre, si vous voulez écrire f(g(x)), c’est bien f (g x) et pas f g x !
⊲Question 1. Que déduire du code ci-contre? ⊳let f x y = () ;;
let a = ref 0 in f (a := 1) (a := 2) ; !a ;;
2 RAPPELS DE PROGRAMMATION IMPÉRATIVE
2.1 CHAMPS MODIFIABLES
En caml, les variables ne sont pas modifiables : une fois qu’une variable a été déclarée par un let, sa valeur
ne change pas (jusqu’à la déclaration suivante).
Si ’a est un type caml,’a ref désigne le type des références contenant une valeur de type ’a. On peut voir
une référence xcomme un tiroir : on peut l’ouvrir pour regarder à l’intérieur (avec !x, on voit un objet de type
’a), ou bien changer son contenu pour y mettre la valeur vde type ’a, (avec x := v).
Pour créer une nouvelle référence, on utilise la fonction let test =
let a, b = ref 1, ref 2 in
let c, d = a, ref a in
a := !a + !b; d := c; !(!d) + !a;;
ref en lui donnant une valeur de départ (la valeur que con-
tiendra le tiroir avant que son contenu ne soit modifié). At-
tention à la subtilité : quand on utilise l’opérateur :=, on
change le contenu de la référence, pas la référence elle-même
(qui désigne toujours le même tiroir) !
⊲Question 2. Quelle est la valeur de la variable test ?⊳
Les cases des tableaux et des chaînes de caractères sont aussi des champs modifiables : tab.(i) et str.[i]
permettent d’obtenir la valeur en i-ème position (en partant de 0) du tableau tab et de la chaîne str. Pour les
modifier on n’utilise pas “:=” mais “<-” : par exemple tab.(i) <- v.
2.2 EXCEPTIONS
Les exceptions sont une manière d’interrompre une partie d’un programme en cas d’erreur. Par exemple,
si vous avez une formule mathématique à calculer, et qu’en plein calcul vous vous apercevez que vous devez
diviser 0, vous allez vous arrêter et vous plaindre que la formule n’est pas bien définie. caml sait faire pareil.
Les expressions sont des objets de type exn qui ressem- #exception Erreur of string;;
let boum () = raise (Erreur "boum");;
try (boum (); "message") with
| Exit -> "sortie"
| Erreur message -> "erreur : " ˆ message
| _ -> "exception inconnue"
blent beaucoup aux types sommes définis dans le précé-
dent TP : ce sont des constructeurs, qui peuvent comporter
des arguments, et sont déclarés par le mot-clé exception.
Quand on a trouvé une erreur, on peut lancer une ex-
pression avec la fonction raise : elle prend une expression
en paramètre, et interromp le calcul (en particulier, tout ce
qui devait se passer ensuite dans le programme n’est pas
exécuté).
Cela permet de faire des erreurs qui stoppent complètement le calcul. Parfois, on voudrait plutôt détecter
l’erreur et utiliser une solution adaptée pour continuer le programme (par exemple si l’erreur est “plus de
papier dans l’imprimante”, il suffit de demander à l’utilisateur de rajouter du papier avant de continuer, au
lieu d’annuler complètement l’impression en cours). On peut rattrapper une exception avec la construction
try <expr> with <filtrage>. Cela se présente un peu comme un match ... with, mais le comportement
est différent :
2