Pourquoi utiliser (aussi) des langages fonctionnels au lycée ?
Guillaume Connan - IREM de Nantes
10 mai 2009
Résumé L’algorithmique fait une entrée remarquée dans le nouveau pro-
gramme de Seconde. Il y est fait clairement mention de l’apprentissage de
l’affectation, des entrées-sorties et des boucles comme allant de soi, ce qui
sous-entend que seule existe la programmation impérative. Cependant la
programmation fonctionnelle est une alternative très proche des mathéma-
tiques et de leur enseignement dans le secondaire. Nous verrons dans quelle
mesure l’enseignement de l’algorithmique via les langages fonctionnels peut
parfois être moins perturbante pour l’élève et le professeur n’ayant pas reçu
de formation récente en algorithmique.
1 Programmation impérative / Programmation fonctionnelle
1.1 Conventions
L’objet de cet article n’est pas d’envisager ces deux modes de programmation avec le point de vue de l’informaticien
cherchant la méthode la plus rapide mais avec celui d’un professeur de mathématiques s’adressant à des élèves
débutants dans ce domaine 1.
Pour beaucoup de professeurs, c’est un sujet oublié voire nouveau : il n’y aura pas de stages pendant l’été ni de livres
à la rentrée. L’urgence est donc à la formation des enseignants. Ce cours article ne fournit donc pas des activités
clé-en-main mais donne des éléments pour alimenter la réflexion du professeur, en particulier en montrant que la
programmation fonctionnelle, souvent méconnue (même si elle est implicite dans un tableur ou utilisée en primaire
avec la tortue Logo), est très proche des mathématique.
Nous ne parlerons pas d’un logiciel en particulier. Cependant, pour les applications pratiques, nous utiliserons
XCAS, logiciel multifonctions spécialement conçu pour être utilisé en classe de mathématiques et OCAML, logiciel
utilisant la programmation fonctionnelle.
1.2 Programmation impérative
La programmation impérative est la plus répandue (Fortran, Pascal, C,...) et la plus proche de la machine réelle. Son
principe est de modifier à chaque instant l’état de la mémoire via les affectations.
Ce mode de programmation présente plusieurs défauts pour un lycéen :
ils s’éloignent des mathématiques en utilisant l’affectation comme base de programmation. Une même variable
peut prendre des valeurs tout à fait différentes selon le moment où on l’évalue alors qu’un élève de seconde
découvre les fonctions qui à un nombre donné associe une unique image ;
la mémoire est constamment modifiée par le programme : le programmeur doit à chaque instant connaître son
état pour savoir ce que représentent les variables affectées ;
on est obligé de créer des variables temporaires pour que certaines zones de la mémoire restent dans un certain
état : cela est source de nombreux bogues dus à une mauvaise maîtrise de la chronologie des affectations.
Prenons l’exemple très simple d’un programme déterminant le successeur d’un entier.
Une case mémoire nommée n reçoit comme valeur 1 :
1. lui-même pouvant d’ailleurs appartenir à cette catégorie !...
1
Écrivons une fonction plus_n qui ajoute k à n :
Alors
renvoie 4 et si on demande à nouveau
on obtient 7.
Ainsi plus_n n’est pas une fonction au sens mathématique car 3 peut avoir des images distinctes !
Bien sûr, il existe des moyens d’y remédier. Par exemple :
Cette fois plus_n_bis(3) renvoie toujours 4 grâce à l’affectation locale donc provisoire de la mémoire sous l’éti-
quette temp.
Il s’agit d’une subtili informatique qui pourrait sembler difficile à assimiler par tous les élèves de Seconde mais qui
est souvent le préalable à toute démarche de programmation impérative. Vu sous cet angle, les efforts nécessaires à
l’enseignement de la notion d’affectation ne semblent pas servir la cause mathématique...
L’algorithme ici est cependant fort simple et nous aurions pu nous passer d’affectation :
Dans la plupart des cas, ce genre d’algorithme sera englobé dans un algorithme plus complexe et on ne pourra se
passer d’affectation si on garde une démarche impérative comme nous le verrons dans les exemples suivants.
1.3 Programmation fonctionnelle
Les langages fonctionnels bannissent totalement les affectations. Ils utilisent des fonctions au sens mathématique
du terme, c’est-à-dire qu’une fonction associe une unique valeur de sortie à une valeur donnée en entrée. Les ef-
fets négatifs listés précédemment disparaissent donc. Les fonctions peuvent être testées une par une car elles ne
changent pas selon le moment où elles sont appelées dans le programme. On parle de transparence référentielle. Au
contraire, une procédure avec effets de bord ne dépend pas uniquement des arguments entrés et donc peut changer
de comportement au cours du programme.
La récursivité est le mode habituel de programmation avec de tels langages : il s’agit de fonctions qui s’appellent
elles-mêmes. Pendant longtemps, la qualité des ordinateurs et des langages fonctionnels n’était pas suffisante et
limitaient les domaines d’application de ces langages.
La notion de récursion n’était jusqu’à maintenant pas au programme de Seconde mais apparaît maintenant dans le
thème « phénomènes d’évolution ».
2
Si nous reprenons notre exemple précédant, nous pouvons faire exprimer aux élèves que l’entier suivant nest égal
à 1+l’entier suivant n1 : on ne sort pas des limites du cours de mathématiques et on n’a pas besoin d’introduire
des notions d’informatique en travaillant sur cette notion.
On peut écrire un algorithme ainsi :
si n=0alors
1
sinon
1+successeur de n1
Algorithme 1 : successeur d’un entier - version récursive
La récursivité n’est pas l’apanage des langages fonctionnels. Par exemple XCAS permet d’écrire des programmes
récursifs :
if
else
Pas de problème pour plus_1_rec(700) mais plus_1_rec(7000) dépasse les possibilités de calcul du logiciel.
Et oui, un langage impératif ne traite pas efficacement le problème de pile, c’est pourquoi pendant longtemps seuls
les algorithmes impératifs ont prévalus.
Remarque : par défaut, XCAS s’arrête au bout de 50 niveaux de récursion. Pour aller plus loin, il faut cliquer sur
à côté de . Régler alors la fenêtre à 1000 par exemple
Utilisons à présent le langage fonctionnel CAML, développé par l’INRIA 2. Même s’il intègre des aspects impératifs
pour faciliter l’écriture de certains algorithmes, il est en premier lieu un langage fonctionnel qui en particulier gère
très efficacement la mémoire de l’ordinateur pour éviter sa saturation lors d’appels récursifs.
let rec
if then
else
Alors par exemple :
Mais
La pile où sont stockés les résultats intermédiaires créés par la récursion est en effet saturée.
Aujourd’hui, les langages fonctionnels sont très efficaces et gèrent de manière intelligente la pile. Ils le font soit
automatiquement, soit si la fonction utilise une récursion terminale, c’est-à-dire si l’appel récursif à la fonction n’est
pas enrobé dans une autre fonction.
Ici, ce n’est pas le cas car l’appel récursif plus_1_rec(k-1) est enrobé dans la fonction x7→ 1+x.
On peut y remédier en introduisant une fonction intermédiaire qui sera récursive terminale :
let rec
if then
else
puis on appelle cette fonction en prenant comme résultat de départ 1 :
let
2. Institut National de Recherche en Informatique et Automatique
3
Alors :
Il n’y a donc aucun problème pour traiter 360 millions d’appels récursifs !
Dans un premier temps, en Seconde, on peut laisser de côté ce problème de récursion terminale et se contenter
de travailler sur de petits entiers. Ainsi, on peut choisir de travailler avec CAML ou XCAS par exemple, même si
ce dernier n’est pas un langage fonctionnel.
2 Comparaison impératif/récursif : quelques exemples
2.1 Suites
La relation un+1=3un+2 valable pour tout entier naturel net la donnée de u0=5 constituent un algorithme
de calcul récursif de tout terme de la suite (un). De telles suites peuvent être rencontrées dans le thème d’étude
« phénomènes d’évolution ».
Sa traduction dans des langages sachant plus ou moins traiter de tels algorithmes est directe.
Par exemple, en XCAS cela devient :
if
else
et en CAML :
let rec
if then
else
Pour la plupart des langages, de telles définitions, qui collent au plus près à la situation mathématique, limitent les
capacités de calcul de l’ordinateur car les diférentes valeurs calculées sont stockées dans une pile.
Cela a entraîné la création d’algorithmes plus longs à écrire et plus éloignés des mathématiques mais qui avaient à
l’époque l’intérêt de soulager la mémoire de l’ordinateur : au lieu de stocker de nombreuses valeurs dans une pile,
on affecte une seule case mémoire aux valeurs de la suite qui sera ré-affectée, au fur et à mesure du déroulement du
programme.
Cela donne en XCAS :
for
Il y avait un problème mathématique et s’y ajoute un mécanisme informatique, l’affectation, qui pourrait dans un
premier temps s’avérer perturbant pour des élèves de Seconde.
2.2 Partie entière
La partie entière n’est pas explicitement au programme de seconde mais sa détermination algorithmique enrichit
l’étude des ensembles de nombres.
On peut définir la partie entière d’un réel xcomme étant le plus grand entier inférieur à x.
4
2.2.1 Algorithme récursif
On part du fait que la partie entière d’un nombre appartenant à [0;1[ est nulle.
Ensuite, on « descend » de xvers 0 par pas de 1 si le nombre est positif en montrant que x⌋ = 1+ ⌊x1.
Si le nombre est négatif, on « monte » vers 0 en montrant que x⌋ = −1+ ⌊x+1.
En CAML :
let rec
if
then
else if
then
else
En XCAS :
if and
else if
else
2.2.2 Algorithme impératif
Pour les nombres positifs, on part de 0. Tant qu’on n’a pas dépassé x, on avance d’un pas. La boucle s’arrête dès que
kest strictement supérieur à x. La partie entière vaut donc k1.
Dans le cas d’un réel négatif, il faut cette fois reculer d’un pas à chaque tour de boucle et la partie entière est la
première valeur de kà être inférieure à x:
Entrées :x(réel)
Initialisation : k 0
début
si x>=0 alors
tant que k<=x faire
kk+1
retourner k-1
sinon
tant que k>x faire
kk-1
retourner k
fin
Algorithme 2 : partie entière d’un réel quelconque
Avec XCAS en Français :
5
1 / 14 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !