Introduction à la programmation fonctionelle La

Transcription

Introduction à la programmation fonctionelle La
Introduction à la programmation fonctionelle
Objectif du cours:
réfléchir aux principes de base de la programmation et de l’informatique à
travers l’apprentissage d’un langage simple mais puissant.
Différence entre “programmation” (concept abstrait) et “programmation sur machine”
(réalisation particulière d’un processus de conception).
relative indépendance du langage vis à vis des problèmes de programmation
le choix du langage tient à deux choses:
puissance d’expression pour résoudre des problèmes complexes et
facilité d’utilisation et d’apprentissage pour se concentrer sur l’essentiel
choix de la programmation fonctionnelle
1
La programmation fonctionnelle ?
concept fondamental: l’abstraction traiter une chose complexe en la divisant en choses
plus simples et en ignorant les détails.
objets de base : la fonction un programme est un ensemble de fonctions traitant des
données d’entrée
des langages interprétés : instructions / interprété au fur et à mesure —
machine
langages compilés :
instructions / préparation (compilation) / execution
avantage/ inconvénients
évaluation / débuggage plus souple
plus lent (mais on peut toujours compiler)
le langage choisi : Camel la programmation fonctionnelle est une famille de langage très
proches, dont le plus célèbre est LISP développé au MIT.
le successeur de LISP: scheme: plus léger, plus simple et aussi puissant, utilisé pour
l’éducation mais pas de typage des données; on utilisera donc un autre langage
fonctionnel typé: Camel
2
A retenir
processus de calcul : êtres abstraits mis en œuvre dans les ordinateurs ;
données : ou information, objets manipulés par les processus ;
programme : contrôle évolution des processus ;
langage de programmation : traduit les processus de façon symbolique
interprète : traduit les processus écrit dans un langage de programmation.
3
Elements de base de la programmation
Le langage de programmation :
permet de donner des instructions ;
constitue un cadre d’organisation des processus de calcul.
grâce généralement à :
des expressions primitives (nombres, fonctions de base)
des moyens de composition pour construire des expressions composees d’expressions
primitives
des moyens d’abstraction pour nommer et manipuler des objets composés comme un
tout, comme si c’était une expression primitive.
Pour la programmation on distingue souvent deux sortes « d’objets »:
les données (par ex. les nombres)
les procédures (par ex. l’addition de nombres)
Les procédures portent généralement sur des objets particuliers
4
Les expressions
l’interprète Camel évalue des expressions
>
Caml Light version 0.74
#1230 ;;
- : int = 1230
la réponse précise le type de la réponse avec sa valeur.
# 10 + (3*4);;
- : int = 22
+, /, * sont des opérateurs décrivant des procédures primitives, les nombres sont des
expressions primitives.
Une expression composée est formée à partir d’expressions (primitives ou non) et
d’opérateurs, terminée par ;;
!#"%$'& ((
5
Les types de base d’expressions
les entiers (int) : les nombres entiers relatifs.
les réels (float) : nombres décimaux. 1.67
les booléens : le vrai (true) et le faux (false).
les caractères (char) : ’a’ ’X’ ’&’
les chaînes de caractères (string) “bonjour”
Les opérateurs n’acceptent que certains types comme arguments. Par exemple, + ne prend
que des entiers :
# "toujours" + 29 ;;
Entrée interactive:
> "toujours" + 29 ;;
> ^^^^^^^^^^
Cette expression est de type string,
mais est utilisée avec le type int.
6
Les définitions
Pour manipuler des objets, nécessité de les nommer: l’opérateur let
#
j
#
#
k
let j = 20 ;;
: int = 20
30 - j ;;
: int = 10
let k = 3* j + 27;;
: int = 87
La définition est le moyen de base de l’abstraction.
Elle permet :
de représenter le résultat d’opérations composées ;
de construire des objets complexes par étapes
développement et test incrémental des programmes.
Pour cela il faut pouvoir définir des procédures, moyen d’abstraction plus puissant que le
nommage d’un objet, en nommant des opérations composées à partir de paramètres.
7
Les fonctions
nécessité de manipuler des fonctions, avec paramètres de différentes sortes, en nombre
différents
besoin d’abstraire les fonctions
ce qui définit une fonction : ses paramètres (appelés variables en maths) et la façon dont
on la calcule;
Par ex. carre : x
x*x
mais une fonction peut l’être de plusieurs choses: l’énergie cinétique en physique,
EC: m v
Pour définir une fonction on spécifie donc les paramètres et le corps:
let cinetik
m v = 0.5 *. m *. v *. v ;;
retourne la fonction
cinetik : float -> float -> float = <fun>
A l’application d’une fonction, par ex. (cinetik 75.5 25.9), les paramètres formels
sont remplacés par les valeurs fournies.
8
Les expressions conditionnelles
Une expression conditionnelle permet l’évaluation d’une expression différenciée selon une
condition (vrai ou fausse). Par exemple la définition de la valeur absolue est une expression
conditionnelle :
si sinon
Elle se traduit en Camel par
let abs x = if x >=0 then x
else -x ;;
9
Conditionnelles (suite)
On peut utiliser les opérateurs suivants sur les conditions (booléens):
= égalité (opérateur polymorphe)
or “ou” logique
& “et” logique
not négation
exercice :
10
Exercices
1. Evaluer les expressions suivantes
10;;
5 + 3 + 4;;
9 - 1.;;
6 / 2;;
let a = 3;;
let b = a + 3 ;;
a + (b * a) ;;
a = b ;;
if a = 4 then 6
else if b = 4 then 6+7+a
else 25 ;;
2. Ecrire une fonction qui calcule la circonférence d’un cercle en fonction de son rayon.
11
Processus et procédures : la récursion
1. Ecrire une procédure qui calcule la factorielle :
&
" & "
"
"
"
2. Ecrire une procédure qui calcule la suite de Fibonacci:
&
&
&
& &
12
"
&
A retenir :
Le sens d’une procédure est indépendant des noms des paramètres formels:
let carre x = x * x;;
let carre y = y * y;;
Les noms des paramètres d’une procédure sont locaux au corps de la procédure
let assez-bon? estimation x =
(abs ((carre estimation) - x)) < .0001 ;;
let carre x = x * x;;
13
Exercices
Ecrire des fonctions réalisant les opérations suivantes :
1. calcul de la norme d’un vecteur (2d) donné par ses coordonnées
2. calcul de la moyenne de deux nombres (réels)
3. calcul du maximum de deux entiers
4. vérifier si 3 nombres correspondent aux longueurs des côtés d’un triangle rectangle
14
Processus et procédures
Pour savoir programmer il faut :
connaître les éléments de base de la programmation
avoir l’expérience de la programmation :
– connaître les procédures les plus utiles
– être capable de prévoir le déroulement des acions qui suivra le processus et de
diriger ce déroulement par un programme.
et maintenant quelques formes typiques de déroulement de processus...
15
Exemple : extraction de racine carrée
différence entre fonctions mathématiques et fonctions programmées
fonction mathématique
procédures informatiques
définit une valeur déterminée par un ou plusieurs
paramètres
produit un résultat
ex
tel que et
mais ne dit pas la valeur exacte...
propriétés
réalisation
16
Exemple : extraction de racine carrée
and now for something completely different... la méthode de Newton par approximations
successives :
au départ si y est une approximation de
, une meilleure approximation est donnée par la
.
moyenne de et
Exemple pour
:
Estimation
Quotient x/y
Moyenne
1
2
1.5
1.5
1.333333
1.4167
1.4167
1.4118
1.41412
1.41412
...
...
Exercice : écrire les procédures qui permettent de calculer la racine avec cette méthode.
17
Exercices
Ecrire des fonctions réalisant les opérations suivantes :
1. le maximum de trois entiers.
2. la puissance quelconque d’un entier (fonction
&
3. la somme des entiers de 1 à n
4. la somme des entiers de p à q
(
(
)
)
5. la somme de deux entiers en utilisant la fonction suivante :
let inc n = 1 + n;;
18
)
Les procédures et les structures de bloc
Racine1 : premier exemple de processus défini par un ensemble de procédures
mutuellement définies.
Décomposition d’un programme en procédures (sous-problèmes):
pourrait être arbitraire ? blocs de 10 lignes
non: l’important est que chaque procédure exécute une tâche bien définie
on n’est pas obligé de s’occuper de la façon dont la procédure calcule ce qu’on lui
demande de calculer: ce qui nous intéresse est le résultat
L’utilisateur d’une procédure n’est pas forcément son auteur
il peut la recevoir comme une boîte noire venant d’un autre, réalisant une certaine
fonction (d’où l’importance de l’explicitation des paramètres, “interface” unique entre la
fonction et le programmeur qui l’utilise.
19
Les procédures et les structures de bloc : noms locaux
les noms des paramètres d’une procédure sont locaux au corps de la procédure; le nom
d’un paramètre de fonction est une variable liée (le sens de l’expression ne change pas si
on renomme le paramètre).
une variable qui n’est pas liée est ... libre
l’ensemble des expressions pour lesquelles une liaison définit un nom est appelé la
portée de ce nom.
les variables liés déclarées comme paramètre d’une procédure ont pour portée le corps de
cette procédure.
les variables libres ont pour portée le corps du programme.
20
Les procédures et les structures de bloc : liaisons locales
Sur l’exemple de la racine carrée, le programme est composée de procédures séparées,
permettant le contrôle de l’usage des noms.
inconvénient : seul l’appel à racine est utile vu de l’extérieur (ce qui peut être un
problème pour les gros programmes)
on peut enfermer les sous-procédures avec des liaisons locales.
let racine x =
let rec ameliore estimation x =
(moyenne estimation (x /. estimation))
and
assez_bon estimation x =
(abs ((carre estimation) -. x)) < 0.0001
and
racine1 estimation x =
if (assez_bon estimation x)
then estimation
else (racine1 (ameliore estimation x) x)
in racine1 1.0 x ;;
21
Structure de données composées
Jusqu’ici on a vu uniquement des données primitives, des types fournis par le langage.
Pour la plupart des problèmes on a besoin de représenter des données plus complexes.
De même qu’à partir de procédures simples on peut faire des procédures composées, on
peut construire des types.
on veut faire une procédure qui donne le min et en même temps le max de deux entiers.
Mais une fonction ne renvoie qu’une valeur.
on peut utiliser un type composé de deux valeurs: un doublet.
Notation : (2,3)
let minmax x y = if x < y then (x,y) else (y,x);;
let minmax x y = (min x y), (max x y);;
De même on peut utiliser des triplets, des n-uplets... (tuples).
22
Comment récuperer une valeur de doublet ?
let zorgbl x y =
let m = minmax x y
in (2 * (fst m) + (snd m));;
let zorgbl x y =
let (m1,m2) = minmax x y
in (2* m1 + m2);;
Intérêt : regrouper des données liées intrinséquement dans un seul objet.
Exemple : les vecteurs.
Si on écrit une somme de 2 vecteurs (à deux dimensions):
let som_vect x1 y1 x2 y2 = (x1+x2),(y1+y2) ;;
Plus structuré (plus abstrait):
let som_vect v1 v2 = (fst v1)+(fst v2), (snd v1)+(snd v2);;
23
Les Listes
Si on a besoin d’un nombre quelconque (et qui peut évoluer) de données similaires, on ne
peut se contenter de tuples (ex: dictionnaire de mots).
Pour cela on peut utiliser des listes: une liste est un ensemble de données de même type.
on note une liste [ donnee1; donnee2 ; ...
; donneep ]
Par exemple une liste d’entiers: [ 2 ; 19 ; 16 ; 23 ; 20 ]
La liste vide est notée []
On peut extraire des éléments d’une liste grâce aux deux opérations suivantes, hd(head),
tl(tail):
hd [ 23 ; 45 ; 78 ];; retourne 23
tl [ 23 ; 45 ; 78 ];; retourne [ 45 ; 78 ]
On peut construire une liste avec les opérateurs suivants :
23::[ 45 ; 67 ] retourne [ 23 ; 45 ; 67]
[96 ; 23]@[ 45 ; 67 ] retourne [ 96 ; 23 ; 45 ; 67]
24
La liste est un type récursif:
une liste est
un élément :: une liste
la plupart des fonctions de listes peuvent etre exprimés de façon récursive.
Ex: compter les éléments d’une liste :
let compter une_liste =
if une_liste=[] then 0
else (1 + compter (tail une_liste));;
25
Exercices
1. Ecrire une fonction qui retourne le maximum d’une liste d’entiers.
2. Ecrire une fonction qui retourne la somme des éléments d’une liste
3. Ecrire une liste qui retourne la liste des carrés des éléments d’une liste entière.
4. Ecrire la fonction map qui retourne la liste des éléments d’une liste auxquels on a
appliqué une fonction f.
ex: (map [1 ; 2; 3] carre)
[1 ; 4 ; 9]
26

Documents pareils