TD Programmation fonctionnelle CS-110
Chapitre 1 : Langage des expressions et des fonctions
Le cours CS-110 est un cours d'introduction à l'algorithmique. Vous
apprenez à créer de "beaux" programmes, concis dans leur expression,
généraux dans leur application et facilement compréhensibles.
Ce but est atteint par l'introduction de techniques d'abstraction
et l'utilisation d'un langage de programmation, CAML, ayant une
syntaxe très simple.
Vous apprenez ainsi dans ce cours des techniques de raisonnement
applicables ensuite avec n'importe quel langage de programmation.
Les travaux dirigés du cours CS-110 vont vous permettre d'approfondir
et d'appliquer les notions vues en cours. Le but de ces TDs est donc
que vous compreniez vraiment le cours de programmation fonctionnelle
et les raisonnements effectués.
N'hésitez donc pas à me poser des questions si quelque chose n'est pas
clair au niveau du cours ou dans un exercice. On est ensemble pour
faire des erreurs dans les exercices, comprendre ces erreurs et
ainsi comprendre le cours plus en profondeur.
Si vous rencontrez une difficulté quelconque sur un exercice lorsque
vous travaillez en dehors des séances, n'hésitez pas à m'envoyer un
mail (Anne.Benoit@imag.fr)
pour pouvoir en discuter, et
pouvoir faire pendant les séances des exercices supplémentaires sur
les points qui ne vous paraissent pas clairs.
C'est en effet en creusant les difficultés que vous rencontrez
que vous pourrez au mieux comprendre et assimiler le cours.
En programmation fonctionnelle, on manipule des expressions et des fonctions.
Les expressions peuvent être de différents types. Nous commençons par exposer
ces types. Nous présentons ensuite la notion d'expression, puis la
notion de fonction.
- les entiers :
,
,
sont de type entier.
- les réels :
,
,
sont de type réel.
- les booléens :
et
sont de type booléen.
- les caractères : un caractère est dénoté en l'entourant
de guillemets. Ainsi,
et
sont de type caractère. L'espace
(
) est un caractère comme les autres.
- les textes : regroupe toutes les chaînes de caractères,
quelle que soit leur longueur. Le texte vide est noté
et le texte
singleton formé d'un caractère est noté par exemple
(pour le
différencier du caractère
). Les textes constitués d'au moins deux
caractères sont notés entre guillemets, comme par exemple
.
Ces types sont construits à partir des types de base.
- les n-uplets : un n-uplet de valeurs est décrit entre des
chevrons (< et >), les valeurs étant séparées par des virgules. Le type
d'un n-uplet est le produit (au sens ensembliste du terme) des types de
chacune des valeurs. Pour définir un produit de types, on peut de manière
équivalente, ou bien décrire un n-uplet de types, ou bien décrire un
n-uplet de champs, un champ étant formé d'un nom et d'un type.
n-uplet de types - intervalle : le type <entier, entier>.
<1, 2> est de type intervalle.
n-uplet de champs - inter : le type <inf : entier, sup : entier>.
<1, 2> est de type inter.
- les tableaux : pour définir un tableau, on décrit son
intervalle de définition et le type de ses éléments.
Elem : un type; T : un tableau sur [3..6] d'Elem
Pour décrire une valeur de type tableau, on énumère entre crochets les
valeurs élémentaires dans l'ordre des indices croissants.
est un tableau d'entiers.
Une expression a un type et une valeur.
,
,
sont des
expressions de base. On peut créer des expressions plus complexes en
utilisant des opérateurs, de la désignation d'expressions ou des
conditionnelles, comme nous le détaillons ci-dessous.
- Les opérateurs arithmétiques
,
, ... ainsi que
les opérateurs de comparaison
,
, ... peuvent
être appliqués aux nombres.
Ainsi,
est une expression de type
entier qui a pour valeur
,
est une expression de type
réel qui a pour valeur
,
est une expression de type booléen
qui a pour valeur
.
- Les opérateurs logiques
,
,
, ... peuvent
être appliqués aux booléens.
Ainsi,
est une
expression de type booléen qui a pour valeur
.
- Sur les caractères, on peut utiliser uniquement les opérateurs
de comparaison
et
.
Ainsi,
est une expression de type booléen qui a pour valeur
.
- Divers opérateurs sont disponibles sur les textes :
- L'opération de concaténation de textes est notée
.
Ainsi,
est une expression de type texte qui a pour valeur
.
- On dispose d'un opérateur pour ajouter un caractère
à gauche ou à droite d'un texte. Ainsi,
et
sont des expressions de type texte qui ont pour valeur
.
- Si t est un texte non vide,
premier(t) dénote le premier caractère du texte t,
fin(t) dénote le texte formé de t sans son premier caractère,
dernier(t) dénote le dernier caractère du texte t,
début(t) dénote le texte formé de t sans son dernier caractère.
Par exemple, pour t=
, premier(t) est une expression de type caractère
qui a pour valeur
, et début(t) est une expression de type texte qui a
pour valeur
.
- Sur les tableaux, on a la notion de sélection pour accéder
à un élément dans le tableau. On utilise la notation indicée pour
sélectionner un élément du tableau.
Ainsi, si T est un tableau d'entiers sur [3..6],
est de type entier
(on peut aussi écrire T[4]).
- Sélection pour les n-uplets de champs :
Si on considère l'expression
<1, 2> qui est de type inter (défini lors de la présentation du type n-uplet),
alors
de <1, 2> est une expression de type entier qui a pour valeur 1,
et
de <1, 2> est une expression de type entier qui a pour valeur 2.
En revanche, on ne peut pas sélectionner directement
les éléments d'un n-uplet de types.
Pour clarifier la compréhension d'une expression, il est souvent utile
de nommer une sous-expression et de l'utiliser ensuite dans une autre
expression.
- soit
dans
: dans l'expression
, toute occurrence
de
est remplacée par la valeur de l'expression
. On dit que la
valeur
est associée au nom
.
- soit
,
...,
dans
: plusieurs
associations nom-valeur sont définies en même temps, mais elles sont
indépendantes les unes des autres : la valeur associée à
n'est pas
connue dans une expression
.
- soit
dans soit
dans ... soit
dans
: dans cette construction imbriquée,
est connu dans
pour
.
Dans tous les cas, l'expression soit ... dans
est du type de l'expression
, et elle a la valeur de
l'expression
évaluée dans un certain contexte.
Nous abordons ici la notion de ``portée'' d'une variable, présente
dans tout langage de programmation. Les exercices de TD puis de TP
permettent de mieux comprendre cette notion.
La notion d'expression conditionnelle
tient une place importante dans la programmation fonctionnelle.
- si
alors
sinon
:
est ici la condition,
c'est une expression de type booléen. Si sa valeur est
, l'expression
vaut
. Sinon elle vaut
.
- selon { description du domaine }
.
. ...
.
. [sinon
]
Ici,
, ...,
sont les conditions, et la valeur de
cette expression dépend de la condition qui est
vraie. Ainsi, si
vaut
, la valeur est celle de
.
Par définition, une et une seule des conditions est vraie.
La partie
est facultative, elle représente la
condition non
et
et non
.
- remarque sur les expressions conditionnelles à valeur booléenne : pour éviter de rendre les programmes illisibles, il est important de remarquer qu'une expression conditionnelle du type ``si
alors
sinon
'' est totalement équivalente à l'expression ``
''. De même, ``si
alors
sinon
'' équivaut à ``
ou alors
'', et ``si
alors
sinon
'' équivaut à ``
et puis
''.
Il est important de remarquer qu'il existe plusieurs façons de passer
un n-uplet de types en paramètre d'une fonction. Nous illustrons ceci
sur un exemple :
diff : <un entier, un entier>
un entier { différence entre les
deux entiers }
Première réalisation : diff(<a, b>) : b - a
Deuxième réalisation : diff(I) : soit <a, b> = I dans b - a
Anne Benoit - Septembre 2001