Considérez l'expressions suivante :
carre 2 + carre 10
Qu'est-ce qui est executé avant : carre 2
ou carre 10
?
Et comment le vérifier ?
Une fonction qui n'a aucun effet sur son environement est appelée pure. Dans ce cas là, l'ordre d'execution n'a pas d'importance, ce qui est un très grand avantage.
Sinon, on dit qu'elle a des effets de bord.
OCaml possède des librairies semblables à printf
pour imprimer à l'écran, mais
nous allons nous restreindre à des fonctions plus basiques.
val print_int : int -> unit
val print_string : string -> unit
val print_endline : string -> unit
unit
#show unit ;;
Le type unit
est un type qui n'a qu'une valeur possible : ()
. Il sert au
fonction qu'un souhaiteraient ne rien retourner car leur unique but est de faire
un effet de bord.
Considérez l'expressions suivante :
carre 2 + carre 10
Qu'est-ce qui est executé avant : carre 2
ou carre 10
?
let scope =
let _ignored_returned_value = print_string "Hello world" in
...
let scope =
let () = print_string "Hello world" in
...
let scope =
print_string "Hello world" ;
...
Un autre effet de bord possible est la mutation de structures de données mutables.
Sauf mention explicite, les structures de données fonctionnelles ne sont pas mutables !
Nous allons voir deux structures de données mutables : les tableaux et les références.
Les tableaux sont une structure de donnée classique en programmation impérative.
let mon_tableau = [| 1; 2; 3 |]
let x = mon_tableau.(1)
let () = mon_tableau.(1) <- 5
let y = mon_tableau.(1)
Quelle valeur à x
à ligne 2 ? Quelle valeur à y
? Quelle valeur à x
à ligne 4 ?
val Array.make : int -> 'a -> 'a array
val Array.init : int -> (int -> 'a) -> 'a array
Une référence est similaire à un tableau qui ne pourrait contenir qu'une seule entrée.
let reference = ref 5
let x = !reference
let () = reference := 10
let y = !reference
let reference = ref 5
let reference_2 = reference
let () = reference := 10
let y = !reference_2