0% ont trouvé ce document utile (0 vote)
102 vues8 pages

Guide OCaml pour Débutants en MP2I

Le document décrit comment installer et configurer l'environnement de développement OCaml, y compris les outils de base, les éditeurs et les sites web pour coder en ligne. Il présente ensuite les types de données fondamentaux en OCaml comme les entiers, les flottants et les booléens.

Transféré par

moimoi
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
102 vues8 pages

Guide OCaml pour Débutants en MP2I

Le document décrit comment installer et configurer l'environnement de développement OCaml, y compris les outils de base, les éditeurs et les sites web pour coder en ligne. Il présente ensuite les types de données fondamentaux en OCaml comme les entiers, les flottants et les booléens.

Transféré par

moimoi
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

MP2I — 2023 – 2024 Fiche Memo Débuts avec OCaml - Gérard Rozsavolgyi LIV, Valbonne

Installation d’OCaml - Travailler en en fin de ligne avec CTRL E. Les bases de OCaml
ligne — Pour l’éditeur (open source) VSCode, voir : https://
marketplace.visualstudio.com/items?itemName= Les types de données fondamentaux
ocamllabs.ocaml-platform pour la configuration.
Installer les outils de base — On peut également installer un noyau OCaml pour Les entiers
Pour tous les systèmes d’exploitations ., il existe des distri- Jupyter-Notebooks : https://github.com/akabe/ 1 # 4 + 5;; OCaml
butions de OCaml : https://v2.ocaml.org/docs/install. ocaml-jupyter, ce qui permet de travailler dans un 2 - : int = 9

html navigateur Web de manière assez simple.


L’installation s’effectue en deux temps : — Si vous êtes utilisateur de l’éditeur Emacs, vous pou- OCaml détermine que le résultat de l’opération 4 + 5 est un
vez utiliser le mode Tuareg : entier de type int. OCaml utilise ici l’inference de type, c’est-
— Installer opam est le plus simple sous Linux ou MacOS,
https://www.emacswiki.org/emacs/TuaregMode. à-dire qu’il déduit le type des variables utilisées et celui du
à l’aide de votre gestionnaire de paquets. Sous MacOS,
installer d’abord un gestionnaire de paquets comme résultat.
Macports (https://www.macports.org/install.php) ou Les données et leurs types en OCaml Les priorités habituelles des opérations sont respectées. En
Homebrew (https://brew.sh). cas d’ambiguïté, un parenthésage implicite à gauche est ap-
Sous Windows, le plus simple est probablement d’ins- Le typage en OCaml est dit typage statique, au contraire du ty- pliqué :
taller WSL qui vous donnera aussi accès aux même page dynamique d’autres langages. La différence réside dans
commandes que sous Linux ou MacOS. Alternative- le moment où un type est associé à chaque expression : res- 1 # 2 + 3 * 5;; OCaml
ment, sous tous les OS, on peut installer Multipass ou pectivement avant ou pendant l’exécution. On retrouve aussi 2 - : int = 17

utiliser des conteneurs Docker. le typage statique en C, par exemple dans la déclaration du 3 # 2 - (3 + 5);;

— Installer un switch type (le int de int x = 42;) au moment de créer une va- 4 - : int = -6

Une fois opam installé, on peut installer sa ou ses riable. Il n’y aura pas de convesrion automatique en cas d’in- 5 # 2 - 3 + 5;;

propres distributions de OCaml. compatibilité du type d’une expression avec le type attendu 6 - : int = 4

Dans un terminal, commencez par lancer opam init par son utilisation. Pour autant, le type d’une expression n’est
pour initialiser la configuration d’opam, puis on va pas forcément précis. Il est déduit en OCaml par les opéra- La division est entière par défaut :
choisir une version de OCaml avec opam switch teurs et fonctions, entre autres, impliqués dans l’expression,
c’est ce qu’on appelle l’inférence de type, ce qui laisse parfois 1 # 11 / 3;; OCaml
create 5.0.0 (version publié le 16/12/2022).
Vous obtenez ainsi une version récente d’OCaml. un doute. Par exemple, la fonction identité sera de type « fonc- 2 - : int = 3
tion qui à une expression de type noté 'a associe un objet 3 # 11 / 3*2;;
En cas de problèmes de compatibilité, on peut égale-
de type 'a » (on parle de polymorphisme). De même, l’opé- 4 - : int = 6
ment installer le switch 4.14.1 qui sera mis à jour au
rateur de comparaison nécessite deux opérandes du même 5 # 11 / (3*2);;
moins jusqu’en 2024.
type, mais celui-ci peut être quelconque. En particulier, on n’a 6 - : int = 1

pas le droit de comparer 0 et 0.0, ce qui risque d’être un peu


Configurer son editeur déstabilisant. La gestion de la mémoire en OCaml est auto- On peut utiliser mod pour obtenir le reste entier :
— L’éditeur le plus minimaliste que vous pouvez utiliser matique. Inutile donc de s’inquiéter avec les allocations.
En outre, il existe un ramasse-miettes pour libérer la mémoire 1 # 9 mod 2;; OCaml
est l’éditeur ligne ledit. Vous pouvez l’installer aisé- 2 - : int = 1
ment via un gestionnaire de paquets sous Linux ou qui n’est plus utilisée.
3 # 9 / 2;;
MacOS. On le lance avec : 4 - : int = 4

Travailler en ligne
> ledit ocaml sh Enfin, sur un processeur 64 bits, les entiers sont compris entre
Quelques sites où l’on peut coder directement en OCaml en
−262 et 262 − 1 (plage inférieure à celle du C)
Il permet d’utiliser l’interpréteur dans un terminal et ligne :
de bénéficier en outre de l’historique des commandes — https://basthon.fr ou Capytale via Moodle. 1 # max_int;; OCaml
via par les flèches haut et bas du clavier. On peut éga- — https://www.france-ioi.org/index.html 2 - : int = 4611686018427387903
lement revenir au début de ligne avec CTRL A et aller — https://try.ocamlpro.com
MP2I — 2023 – 2024 Fiche Memo Débuts avec OCaml - Gérard Rozsavolgyi LIV, Valbonne

3 # min_int;; 4 - : float = 1. Les booléens


4 - : int = -4611686018427387904 5 # 2.17e-5 *. 1.18e-17;;
6 - : float = 2.5606e-22
On peut travailler avec des nombres écrits dans différentes — Les booléens sont true et false.
7 # sqrt(2.);;
bases. Il suffit de les faire précéder de 0b pour la notation bi- — Les opérateurs de comparaison comme =, ==, <, > ren-
8 - : float = 1.41421356237309515
naire, 0o pour l’octal et 0x si l’on souhaite écrire en hexadéci- voient des booléens.
9 # 2.**10.;;
mal : — Les opérations booléennes de base sont : not, && (et)
10 - : float = 1024.
et || (ou).
11 # 5.0/.0.;;
1 # 0b1010;; OCaml 12 - : float = infinity
2 - : int = 10 13 # -5.0/.0.;;
3 # 0xb;; 14 - : float = neg_infinity
4 - : int = 11
5 # 0xbb;; 1 # 17 > 2;; OCaml
- : int = 187 Mais attention, elles peuvent évidemment donner lieu à des
6 2 - : bool = true
erreurs d’arrondi !
3 # 2 == 1;;
Les flottants 4 - : bool = false
Les nombres décimaux sont de type float. Ils sont représen- 1 # 0.1 +. 0.1 +. 0.1 -. 0.3;; OCaml 5 # 17 >= 3;;
tés en interne au format IEEE 754 avec une mantisse 𝑚 et un 2 - : float = 5.5511151231257827e-17 6 - : bool = true
exposant 𝑛. 7 # (5 < 2) && ( 17 > 3);;
8 - : bool = false
On peut vouloir convertir un entier en flottant, il s’agit d’un .
1 # 10.;; OCaml 9 # (5 > 1) || (17 = 2);;
2 - : float = 10. 10 - : bool = true
1 # float(2) +. 2.2;; OCaml 11 # not(17 = 2);;
Les opérations entre entiers et floats ne sont pas très harmo- 2 - : float = 4.2 12 - : bool = true
nieuses : 3 # float 2 +. 2.2;;
4 - : float = 4.2
1 # 1.1 + 2;; OCaml
2 Error: This expression has type float but an
↪ expression was expected of type int et inversement, pour passer d’un float à un int :
Pour les comparaisons de booléens ou d’entiers, on peut uti-
OCaml est bien discipliné et ne réalisera pas de conversion liser les opérateurs = ou == : Voir plus bas pour les types de
1 # int_of_float(sqrt(2.));; OCaml
implicite pour vous ! Vous devez expliciter votre opération, en données plus complexes.
2 - : int = 1

expliquant qu’elle concerne bien les floats ce qui est un peu


contraignant et alourdit la syntaxe mais permet à l’inférence
de type de fonctionner dans tous les cas. Il existe aussi une fonction floor, distincte de int_of_float :

Attention ! 1 # floor(sqrt(3.));; OCaml 1 # let x = 2;; OCaml


1 Les opérations arithmétiques impliquant les 2 - : float = 1. 2 val x : int = 2
floats doivent toutes être suivies d’un point. 3 # int_of_float(sqrt(3.));; 3 # let y = 2;;
4 - : int = 1 4 val y : int = 2
5 # floor(-.sqrt(3.));; 5 # x = y ;;
1 # 1. +. 2.1 ;; OCaml 6 - : float = -2. 6 - : bool = true
2 - : float = 3.1 7 # int_of_float(-.sqrt(3.));; 7 # x == y ;;
3 # log(exp(1.));; 8 - : int = -1 8 - : bool = true
MP2I — 2023 – 2024 Fiche Memo Débuts avec OCaml - Gérard Rozsavolgyi LIV, Valbonne

Les chaînes et les caractères 1 # let liste = [1;2;3] ;; OCaml Attention !


Les string sont entourés de guillemets (double quotes) et on 2 val liste : int list = [1; 2; 3]
les concatène avec ^ tandis que les char sont stockés entre La comparaison entre floats est probléma-
3 # 0::liste ;;
simples quotes : tique à deux titres :
4 - : int list = [0; 1; 2; 3]
— Tout d’abord il faut bien penser à uti-
5 # [1;2] @ [3;4];;
# "Hello " ^ "le Monde !";; OCaml liser les opérateurs spécialisés +., *.,
1 6 - : int list = [1; 2; 3; 4]
2 - : string = "Hello le Monde !" etc. pour réaliser des opérations sur les
floats.
Attention ! — Ensuite, les erreurs d’approximation
1 # 'c';; OCaml
sur les floats peuvent faire que les com-
2 - : char = 'c' Les listes de types hétérogènes ne sont pas ad- paraisons deux types sont érronées :
mises !
Correspondances entre char et codes ASCII : 1 On les utilise souvent avec des fonctions ré- 1 OCaml
# let x = 0.1 +. 0.1 +.
cursives ou List.iter ou List.map ↪ 0.1 ;;
1 # int_of_char 'a';; OCaml 2 val x : float =
2 - : int = 97 ↪ 0.300000000000000044
3 # char_of_int 97;; 3 # let y = 0.3;;
4 - : char = 'a' 4 val y : float = 0.3
Comparaison structurelle et physique 5 # x = y;;
- : bool = false
Les tuples
6

— L’opérateur = est l’opérateur d’égalité structurelle. Il 7 # x == y;;


compare deux valeurs pour évaluer si elles ont la - : bool = false
Entre parenthèses, ils permettent de gérer des n-uplets de 8

même structure et les mêmes contenus. # x -. y;;


plusieurs valeurs potentiellement hétérogènes : 9

— L’opérateur == est l’opérateur d’égalité physique. Il 1 10 - : float =


1 # (1,"1",1.0,'1');; OCaml compare deux valeurs pour voir si elles occupent ↪ 5.5511151231257827e-17
2 - : int * string * float * char = (1, "1", le même emplacement mémoire (donc partagent la
↪ 1., '1') même valeur).

1 let a = [1; 2; 3];; OCaml


Listes OCaml 2 let b = [1; 2; 3];;
3 let c = a;;
Il existe un type tableau (ou vecteur) comme dans de nom- 4 a = b;; (* true *)
breux langages. Sa longueur est fixée lors de sa création ce qui 5 a == b;; (* false *)
permet d’avoir accès à chaque composante : 6 a == c;; (* true *)
1 # let t = [|1;2;3|] ;; OCaml
2 val t : int array = [|1; 2; 3|] Attention !
3 # t.(2) ;;
4 - : int = 3 Deux valeurs qui sont égales selon == sont
toujours égales selon =, mais la réciproque
Il existe un type liste dynamique. On n’a accès en standard n’est pas nécessairement vraie. Si vous avez
qu’à son premier élément et au reste. On a cependant un opé- deux structures de données distinctes qui
1 contiennent les mêmes valeurs, elles peuvent
rateur binaire de concaténation de listes @ (semblable au + en
Python) : être égales selon =, mais pas selon ==.
MP2I — 2023 – 2024 Fiche Memo Débuts avec OCaml - Gérard Rozsavolgyi LIV, Valbonne

Création de types 1 # let (x,y) = (2.,10.) in x ** y ;; OCaml avec des booléens :


2 - : float = 1024.
C’est l’un des points forts d’OCaml : 1 # let bissextile annee = OCaml
Pour des énumérations ou types sommes :
Déclarations simultanées 2 (annee mod 4 = 0 && (annee mod 100) != 0) ||
On utilise le mot clef and (qui aura aussi un autre usage) : ↪ (annee mod 400) = 0;;
1 (* Enumérations *) OCaml 3 val bissextile : int -> bool = <fun>
2 type couleur = Trefle | Carreau | Coeur | # bissextile(2024);;
1 # let a= 17 and b = 19;; OCaml 4
↪ Pique - : bool = true
2 val a : int = 17 5
3 # [Trefle ; Carreau] ;;
3 val b : int = 19
4 - : couleur list = [Trefle; Carreau] On peut disjoindre des cas grâce au ou :
4 # a + b ;;
5 - : int = 36
Notez les majuscules initiales. 1 # let trigo = function OCaml
mais ausi : On peut réaliser la même chose avec des tuples, à la manière 2 | 0. -> 0.5
de Python : 3 | x -> (1.-.cos(x))/.(x*.x);;
1 (* Enregistrements *) OCaml 4 val trigo : float -> float = <fun>
2 type point = { x : float; y : float } 1 # let (c1,c2) = ('a','b');; OCaml 5 # trigo(0.);;
2 val c1 : char = 'a' 6 - : float = 0.5
1 (* Option *) OCaml 3 val c2 : char = 'b' 7 # trigo(0.0001);;
2 type 'a option = None | Some of 'a 8 - : float = 0.499999996961264515

Fonctions On peut rendre le paramètre du filtrage explicite avec la syn-


1 (* Par cas *) OCaml
taxe match with :
2 type figure = Une expression fonctionnelle est constituée d’un paramètre
3 | Rectangle of point * point formel (le nom de la variable) suivi d’un corps qui est lui 1 let rec factorielle n = match n with OCaml
4 | Cercle of point * float même une expression licite en OCaml. 2 | 0 -> 1
On peut créer des fonctions avec function ou fun : 3 | n -> n * factorielle (n-1);;

Les déclarations 1 # let delta = OCaml Et utiliser le cas par défaut (tout autre cas), signalé par un _ :
fun (a, b,c) -> b*b - 4*a*c;;
let
2

3 val delta : int * int * int -> int = <fun> 1 # let nand a b = OCaml
A la manière d’autres langages, comme Javascript. 4
2 match (a, b) with
5 # delta(1,2,3);; 3 | (true, true) -> false
1 # let x = 3 * 4;; OCaml - : int = -8
6
4 | _ -> true;;
2 val x : int = 12
5 val nand : bool -> bool -> bool = <fun>
Notez que delta est bien décrite par OCaml comme une fonc-
Déclarations locales
6 # nand true true;;
tion : 𝑖𝑛𝑡 ∗𝑖𝑛𝑡 ∗𝑖𝑛𝑡− > 𝑖𝑛𝑡 =< 𝑓𝑢𝑛 > qui indique qu’il s’agit 7 - : bool = false
On peut définir localement une variable, avec une portée li- d’une fonction de ℤ3 dans ℤ. 8 # nand false false;;
mitée à l’expression où elle a été définie : On peut également déclarer la fonction sous la forme : 9 - : bool = true

1 # let x = 41 in x + 1 ;; OCaml 1 # let delta = fun (a,b,c) -> b*b-4*a*c;; OCaml


1 # let xor a b = OCaml
2 - : int = 42
3 (* La définition est bien locale : *) ou sous une forme plus basique : 2 match (a, b) with
4 # x;; 3 | (true, false) -> true
1 # let delta(a,b,c) = b*b - 4*a*c;; OCaml 4 | (false, true) -> true
5 Error: Unbound value x
2 val delta : int * int * int -> int = <fun> 5 | _ -> false;;
MP2I — 2023 – 2024 Fiche Memo Débuts avec OCaml - Gérard Rozsavolgyi LIV, Valbonne

6 val xor : bool * bool -> bool = <fun> 2 val carre' : float -> float = <fun> On peut à présent composer des fonctions, cette fois avec des
7 # xor true true;; 3 # carre' 3.;; types génériques :
8 - : bool = false 4 - : float = 6.00000049644222599
9 # xor true false;; 1 # let compose f g = fun x -> f (g x);; OCaml
10 - : bool = true 2 val compose : ('a -> 'b) -> ('c -> 'a) -> 'c
Ce qui semble une approximation raisonnable … ↪ -> 'b = <fun>

Mais on peut également définir une fonction derivee géné-


Fonctions : des citoyens de première classe Le type de compose s’explique comme suit :
rique calculant une dérivée approchée pour une fonction 𝑓 — Le premier argument 𝑓 désigne ici une fonction trans-
On peut tout d’abord utiliser comme en Python, Haskell, Ja- quelconque : formant un type de variable 𝑎 en un type 𝑏.
vascript ou Java des fonctions anonymes en OCaml : Ces fonc- — Le second argument 𝑔 est une fonction transformant
tions sont également appelées ou : un type de variable 𝑐 en un type 𝑎.
1 # let derivee f = deriv f 1e-5;; OCaml
— La fonction composée résultante transforme ainsi un
1 # (fun x -> x * x );; OCaml 2 val derivee : (float -> float) -> float ->
type de variable 𝑐 en un type de variable 𝑏.
2 - : int -> int = <fun> ↪ float = <fun>
3 # (fun x -> x *. x );;

4 - : float -> float = <fun> Conditionnelles et définitions locales


Puis l’utiliser avec la fonction carre au point 3 :
Que l’on peut également appliquer directement : On peut faire usage de structures conditionnelles pour définir
des fonctions :
1 # (fun x -> x * x )2;; OCaml 1 # derivee carre 3.;; OCaml
2 - : int = 4 2 - : float = 6.0000099999513159 1 let valeur_abs(x)= OCaml
2 if x >= 0 then x
On peut facilement passer des fonctions en paramètres à 3 else -x;;
d’autres fonctions : puis de même définir une fonction dérivée seconde par : 4 val valeur_abs : int -> int = <fun>

1 # let derive f dx = fun x -> (f (x +. dx)OCaml


-.
↪ f x) /. dx;; 1 let derivee_seconde f = derivee (derivee OCaml Fonctions récursives
2 val derive : (float -> float) -> float -> ↪ f);;
↪ float -> float = <fun> C’est une fonction construite en s’invoquant elle-même. Seul
le modificateur rec après let la distingue d’une fonction or-
Le type un peu complexe de la fonction derive se décompose Puis calculer la dérivée seconde en 3 de la fonction carre : dianaire :
de la manière suivante :
— Premier argument (float -> float) : la fonction 𝑓. 1 let rec factorielle = function OCaml
— Le deuxième argument, de type float : la valeur 𝑑𝑥. 1 # derivee_seconde carre 3.;; OCaml 2 | 0 -> 1
— Valeur de retour de type float -> float : la valeur de 2 - : float = 2.000017929049136
3 | n -> n * factorielle(n-1);;
retour de la fonction deriv est une fonction qui à un 4 val factorielle : int -> int = <fun>
float associe un float. 5

Si nous reprenons la fonction anonyme fun x -> x *. x Attention ! 6 let rec fact(n)=
carre, nous pouvons à présent calculer la dérivée approchée 7 if n=0 then 1
de cette fonction au point 𝑥 = 3 grâce aux fonctions compose Ce n’est pas une méthode très fiable pour cal-
8 else n*fact(n);;
et carre. culer des dérivées secondes car les erreurs
9 val fact : int -> int = <fun>
1 d’arrondi dans les différences finies vont se cu-
1 # let carre' = deriv (fun x -> x *. x) OCaml muler. Par exemple avec un dx = 1e-10, on
↪ 1e-10;; obtient un résultat erroné.
Définition locale de fonctions
MP2I — 2023 – 2024 Fiche Memo Débuts avec OCaml - Gérard Rozsavolgyi LIV, Valbonne

1 let nb_sol(a,b,c) = OCaml On peut toujours programmer en impératif 1 # !x + 1 ;; OCaml


2

3
let delta(a,b,c) =
b*b - 4*a*c
Type unit 2 - : int = 2
Il existe des fonctions qui jouent le rôle dévolu aux procé-
4 in if delta(a,b,c) = 0 then 1
dures dans les langages impératifs et qui sont à effets de
else if delta(a,b,c) < 0 then 0
bords. Ocaml étant typé, un type est tout de même affecté à
5

6 else 2;; On peut réaliser de nouvelles affectations en utilisant les ré-


ces fonctions : unit.
férences :
1 # print_string "Youkoulélé" ;; OCaml
2 Youkoulélé- : unit = ()

Récursion terminale Une autre action à effet de bord est la modification en place 1 # x := !x + 3 ;; OCaml
d’un (array) à l’aide de l’opérateur <- : 2 - : unit = ()
3 # x;;
1 let rec succ = function OCaml 1 # let v = [|1;2;3|];; OCaml 4 - : int ref = {contents = 4}
2 |0 -> 1 2 val v : int array = [|1; 2; 3|] 5 # !x ;;
3 |n -> 1 + succ(n-1) ;; 3 # v.(2) <- 42 ;; 6 - : int = 4
4 val succ : int -> int = <fun> 4 - : unit = ()
5 5 # v ;;
6 # succ(100000);; 6 - : int array = [|1; 2; 42|]
7 - : int = 100001
8 # succ(1000000);; Remarque 1
À retenir
9 Stack overflow during evaluation (looping
recursion?). On remarque au passage qu’une réaffectation est bien
↪ On évitera ce genre d’action à effet de bord
du type unit.
partout où c’est possible.

On arrive à la limite de la pile.


Références
Le langage Caml oblige à distinguer une référence et son Boucles
1 let succ(n) = OCaml contenu. On ne pourra ainsi pas écrire x := x + 1 comme
2 let rec local = function en C par exemple. Une référence est crée avec ref, et pour La syntaxe est relativement usuelle mais il faut bien faire at-
3 | (0,acc) -> acc accéder à son contenu, on doit invoquer ! : tention à la distinction référence/contenu :
4 | (n,acc) -> local(n-1,1 + acc)
5 in local(n,1);; 1 # let x = ref 1 ;; OCaml
6 val succ : int -> int = <fun> 2 val x : int ref = {contents = 1}
7 3 # x;; 1 (* Boucle for *) OCaml
8 # succ(100000000);; 4 - : int ref = {contents = 1} 2 # let sum(n) =
9 - : int = 100000001 3 let s = ref 0 in
Mais on ne peut pas invoquer : 4 for i=1 to n do
5 s := !s + i
Astuce 1 # x * 2 ;; OCaml 6 done;
2 Error: This expression has type int ref 7 !s;;

OCaml est capable de dérécursifier les récur- 3 but an expression was expected of type 8 val sum : int -> int = <fun>
sions terminales et n’utilise alors plus sa pile ↪ int 9 # sum(100);;
qui ne peut donc plus être saturée. 10 - : int = 5050
il faut écrire :
MP2I — 2023 – 2024 Fiche Memo Débuts avec OCaml - Gérard Rozsavolgyi LIV, Valbonne

1 (* Boucle While *) OCaml ou encore, en utilisant les opérateurs standards d’addition et 3 val ( ++ ) : int * int -> int * int -> int *
2 # let sum_w(n) = de multiplication d’OCaml qui attendent deux arguments, on ↪ int = <fun>
3 let s = ref 0 in peut fixer l’un des deux pour obtenir simplement des fonc-
4 let i = ref 0 in tions d’incrémentation ou de multiplication par deux :
Que l’on utilise ensuite comme ceci :
5 while (!(!i <= n)) do
6 begin 1 let inc = ( + ) 1;; OCaml
7 s := !s + !i; 1 # (3, 4) ++ (5, 6);; OCaml
8 incr i; 1 let double = ( * ) 2;; OCaml 2 - : int * int = (8, 10)
9 end
10 done;
11 !s;; Immutabilité en OCaml
12 val sum_w : int -> int = <fun>
En OCaml, lorsqu’une valeur est créée, elle ne peut pas Conventions de nommage en OCaml
13
être modifiée. On parle d’immutabilité. Cela contraste avec
14 # sum_w(100);; — Identificateurs (variables et fonctions) : en
d’autres langages où les valeurs (ou objets) peuvent être mo-
15 - : int = 5050 ”snake_case” en minuscules, doivent être clairs et
difiées après leur création, qu’on appelle mutabilité.
Par exemple, quand on crée une liste ou un enregistrement, explicites, parfois au détriment de la concision.
on ne peut pas changer les éléments de la liste ou les champs — Modules : Utilisent le ”CamelCase” avec majuscule ini-
Signature, curryfication et fonctions partielles de l’enregistrement en place. Si on veut une liste avec des élé- tiale comme : MyFunction, UserDetails ou Montant-
ments modifiés ou un enregistrement avec des champs diffé- Total. Les noms de modules devraient être descriptifs
1 let module_carre (x, y) = x *. x +. y *. OCaml
y;; rents, il faut créer une nouvelle liste ou un nouvel enregistre- et indiquer clairement ce que le module contient ou
ment. fait.
La signature d’une fonction est l’information sur les types des — Constantes : OCaml ne distingue pas explicitement les
arguments et de la valeur de retour. Elle est donnée en OCaml 1 let liste_ori = [1; 2; 3] OCaml constantes des autres variables, mais on peut éven-
par la syntaxe : 2 let ma_nouvelle_liste = 0 :: liste_ori
tuellement utiliser des lettres majuscules ou un préfixe
nom : type_arg1 → type_arg2 → ⋯ → type_retour 3 (* Crée une nouvelle liste [0; 1; 2; 3] *)
pour indiquer une valeur constante. Une autre pra-
La fonction précédente a pour signature module_carre 4 (* liste_ori est inchangée *)
tique courante est d’utiliser un module pour grouper
: float * float → float, et la console affiche val des constantes liées.
module_carre : float * float → float = <fun>. ou encore, pour un type enregistrement : — Types et variantes : Les noms de types utilisent généra-
Ce qu’il faut comprendre, dans la syntaxe précédente de la lement le ”snake_case”, comme les identificateurs. Les
signature d’une fonction, c’est qu’en fait la fonction nom n’at- 1 type point = { x : float; y : float } OCaml constructeurs de variantes utilisent le ”CamelCase”,
tend qu’un argument et retourne une autre fonction de signa- 2 let p = { x = 1.0; y = 2.0 };; comme les modules.
ture 3 let p_modifie = { p with x = 3.0 } — Type de champs d’enregistrement et de noms de la-
nom1 : type_arg2 -> ... -> type_retour, pour laquelle 4 (* Crée un nouveau point avec x = 3.0 et y = bels : Utilisent généralement le ”snake_case”.
le principe est le même. ↪ 2.0 *) — Signatures et functors : Suivent généralement les
mêmes règles que les modules, utilisant le ”Camel-
Il est donc tout à fait possible de définir une fonction partielle
Case”.
à partir d’une telle fonction en renseignant successivement
des arguments.
Définition d’opérateurs infixes — Opérateurs infixes personnalisés : Doivent
commencer et finir par un caractère parmi
Tester à ce sujet le code suivant : On peut également définir nos propres opérateurs infixes en ! $ % & * + - . / : < = > ? @ ^ |.
OCaml. Par exemple, définissons un opérateur pour addition- — Commentaires et documentation : Les commentaires
1 let add x y = x + y;; OCaml ner deux paires : devraient être clairs et bien écrits, suivant les conven-
2
tions grammaticales standard. Utiliser des commen-
3 let add3 = add 3;; 1 # let (++) (x1, y1) (x2, y2) = OCaml
taires spéciaux ((** ... *)) pour la documentation qui
4 add3 4;; 2 (x1 + x2, y1 + y2);;
peut être extraite avec des outils comme ocamldoc.
MP2I — 2023 – 2024 Fiche Memo Débuts avec OCaml - Gérard Rozsavolgyi LIV, Valbonne

Quelques ressources intéressantes


— Une très riche introduction à OCAML par l’un de ses
pères :
https://caml.inria.fr/pub/distrib/books/manuel-
cl.pdf
— Le manuel de référence de CAML en français, par Xa-
vier LEROY et Pierre WEIS :
http://caml.inria.fr/pub/distrib/books/manuel-
cl.pdf
Version plus récente en Anglais (couvrant OCaml >=
5) : https://v2.ocaml.org/manual/
— Ouvrage de référence CAML :
http://www.pps.jussieu.fr/Livres/ora/DA-OCAML/
— Un tutoriel en français : https://ocaml-tutorial.org/fr

Vous aimerez peut-être aussi