Ceci est une ancienne révision du document !
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 1 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 172
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Table des matières
Initiation à OCaml
Je vous propose de découvrir la programmation avec OCaml, un langage purement fonctionnel. C'est un langage essentiellement développé en France notamment par l'INRIA. C'est un langage développé par des universitaires avec une approche très formelle.
C'est un langage difficile à maîtriser, on va se limiter aux bases.
Pour faire des tests, vous pourrez utiliser un environnement en ligne
Console, programme
Comme souvent, vous disposez à la fois d'une console dans laquelle vous pouvez entrer des commandes qui seront exécutées immédiatement. Le prompt de la console est représenté par le caractère #.
Vous pouvez aussi enregistrer vos commandes dans un fichier et les exécuter ensuite.
Commentaires
(* ceci est un commentare qui peut faire plusieurs lignes *)
Fin de commande
Pour indiquer la fin d'une commande, on utilise ;;
Expressions de base
D'abord il faut distinguer les types int et float ainsi que leurs opérateurs.
3 est un int. 3. est le même nombre mais en version float.
De la même façon, + est l'addition, mais l'addition uniquement pour les entiers.
Si on veut additionner des float, on utilise +..
3 + 4;; (* affiche 7 en précisant le type int*) 3. +. 4.2;; (* affiche 7.2, type float*) 3 +. 4.2;; (* Erreur ! 3 n'est pas un float*)
Assignation
let x = 3;;
Le mot clé let peut être compris comme le soit des mathématiciens : Soit x égal à 3.
Attention : Il n'y a pas vraiment de variables en programmation fonctionnelle. x ne pourra pas changer ! C'est une constante.
On peut néanmoins créer des variables en OCaml. Nous n'en parlerons pas.
On peut aussi définir une quantité qui n'existera que le temps d'une expression :
let a = 2 in a+7;; (* renvoie l'entier 9 *)
Dans ce qui précède, a n'existe que le dans le temps de l'expression qui suit.
On peut d'ailleurs enchaîner :
let a = 3 in let b = 11 in a * b;; (* renvoie 33 *) let r = let a = 12 in a + 15;; (* assigne la valeur 12 + 15 = 29 à r mais a n'existe que le temps de la ligne *)
Conditions
Opérateurs classiques. On utilise || pour le OU, && pour ET et enfin not pour la négation.
let x = 19;; x > 3;; (* renvoie true *) x < 25 && x < 0;; (* renvoie false *)
Bloc de test
if condition then instruction;; (* avec else *) if condition then instruction else instruction;;
Exercices
Testez les expressions suivantes. Essayez de deviner le résultat puis vérifier dans OCaml, corrigez-les au besoin.
let r = let x = 7 in 6 * x;; let a = (r - 6) / 6 - 6;; let o = r * r - x * x - 51;; let u = let x = 9 in if (x>9) then 9/x else x/9;;
Corrigez ces expressions
let pi_sur_4 = 3.14 / 4.;; let dans_l_ordre = 1 < 2 < 3;; let positif = let a = 42 in if a >= 0 then true;; let double_absolu = let x = -2.7 in (if x>0 then x else -x) *. 2;;
Fonctions
Évidemment, dans un langage fonctionnel, cette partie est très importante.
let f = fun x -> x+1;; (* affiche : val f: int -> int = <fun> *)
On a assigné à f une fonction en utilisant le mot-clé fun. Cette fonction est comme une fonction mathématique, elle consiste en l'association d'un item à un autre.
La fonction est ici reconnue comme associant un entier à un entier.
On pourra calculer :
f 5;; (*affiche 6*) f(5);; (*idem*)
Exercices
- Écrire une fonction cube de type
float -> floatqui élève son argument au cube. - Écrire une fonction
is_positivede typeint -> boolqui teste si son argument est positif ou nul. - Écrire une fonction
is_evende type `int → bool` qui teste si son argument est pair.
On pourra utiliser l’opérateurmodcalculant le reste dans une division euclidienne.
Fonction à plusieurs variables
Une fonction à deux variables devient un peu plus bizarre :
let g = fun x y -> x * y;; (* renvoie val g: int -> int -> int <fun> *) g 4 13;; (* renvoie 52 *) g(4,13);; (* Erreur ! *) g 4;; (* renvoie une fonction int -> int ??? *) g(4);; (* idem *) g(4)(13);; (* renvoie 52 *)
Il faut comprendre que la fonction g reçoit d'abord l'argument x, disons x = 4 pour l'exemple. x étant connu, on sait que le résultat sera 4 * y.
g 4 produit donc une fonction y -> 4 * y.
Puisque g(4) est une la fonction y → 4 * y on peut lui appliquer un argument : g(4)(13) qui fait 52.
Remarquez que les parenthèses sont inutiles et ne servent qu'à préciser une priorité en cas de besoin.
Par exemple :
f f 5;; (* Erreur : le premier f essaie de prendre le 2e f comme argument *) f (f 5);; (* C'est bon, le premier f prendra le résultat de (f 5) comme argument, c'est à dire 6*)
Exercice
- Écrire une fonction qui calcule le produit de 3 entiers donnés en argument,
- Écrire une fonction qui détermine si trois arguments entiers positifs forment un triplet pythagoricien – comme 3, 4, 5 qui vérifient $3^2 + 4^2 = 5^2$
Fonction comme argument
Une fonction peut avoir une une fonction comme argument. Par exemple, on pourrait définir une fonction repete consistant, à partir d'une fonction $x \mapsto f(x)$ d'obtenir la fonction $x \mapsto f(f(x))$.
let repete f = fun x -> f ( f x );; (* ou, c'est équivalent *) let repete f x = f ( f x ) ;; (* Exemple d'utilisation : *) let g = fun x -> 3 * x + 2;; let h = repete g;; (* h est la fonction x -> g(g(x)) *) g(1);; (* renvoie 5 *) g(5);; (* renvoie 17 *) h(1);; (* renvoie 17, c'est à dire g(g(1)) *)
Cas de la récurrence
OCaml autorise les fonctions récurrentes mais il faut alors préciser le mot clé rec.
Par exemple, le classique factoriel :
let rec facto = fun n -> if n >= 1 then n * (facto (n-1) ) else 1;;
La récurrence est le chemin privilégié. Supposez que vous souhaitiez faire la somme des n premiers entiers. Il serait naturel d'écrire
(* attention code faux *) let n = 10;; let t = 0;; for i = 1 to n do t = t + i; done;; print_int t;;
Mais cela ne fonctionne pas : La commande t = t + i suppose de modifier la valeur de t ce qui n'est en principe pas possible ! Il faut passer par une récurrence.
Exercice
Écrivez une fonction somme recevant l'argument n et calculant la somme des entiers de 1 à n.
Définition par cas
La fonction facto précédente prévoyait deux cas : n = 0 ou n quelconque.
Il pourrait y avoir plus de cas et OCaml prévoit une syntaxe pour cela :
let rec facto = function | 0 -> 1 | n -> n * (facto (n-1)) ;;
Il suffit d'énumérer les cas possibles et d'indiquer quoi faire à chaque fois.
Listes
On dispose d'une structure de liste.
let x = [4;5;17];; let y = 15::x;; (* liste [15;4;5;17] *) let z = 12::13;; (* erreur, pas autorisé *)
Avec une fonction on peut accéder au premier élément d'une liste (head) et à la queue (tail, éléments suivants). Voici un exemple donnant la somme des éléments d'une liste.
let rec somme = function
| [] -> 0 (* si la liste est vide *)
| hd::tl -> hd + (somme tl);;(* hd = head = 1er élément
tl = tail = éléments suivants.*)
somme x;; (* renvoie 26 *)
Exercice
- Écrivez une fonction
longueurdonnant la longueur d'une liste. - Soit un
polynomeà coefficient entiers, par exemple $x^5 + 3\,x^2 - 4\,x + 2$. On peut représenter ce polynôme par une liste[2, -4, 3, 0, 0, 1]où chaque terme représente le coefficient de $x$ à la puissance donné par l'indice du terme. Par exemple,3à l'indice 2 signifie $3\,x^2$.
Écrivez une fonction qui donne la liste dérivée, c'est à dire ici[-4, 6, 0, 0, 5]pour $5\,x^4 +6\,x -4$.
