Programmation Fonctionnelle et Origines des Langages

1/66
100%

<!-- Slide number: 1 -->

Programmation Fonctionnelle

Chapitre I :

Introduction

BEJI Faryel

1

<!-- Slide number: 2 -->

ML, Lisp, and Haskell are the only programming languages that I've seen where one spends more time thinking than typing.    Philip Greenspun

![](Picture5.jpg)

![](Picture3.jpg)

![](Picture5.jpg)

![](Picture4.jpg)

2

<!-- Slide number: 3 -->

Plan

I- Avant Propos

II- Programmation Impérative /Déclarative

III-Historique de la PF

IV- Paradigmes de Programmation

V- Intelligence Artificielle et PF

VI- Langages de PF

3

<!-- Slide number: 4 -->

I- Avant Propos

Souvent présentés comme le summum de la technologie, les ordinateurs sont en fait des machines assez simples (dans leur principe), fabriquées à partir de quelques types de circuits élémentaires :

registres, mémoires, additionneurs, décodeurs etc...

4

<!-- Slide number: 5 -->

Ces machines fonctionnent de la manière suivante :

  • elles exécutent séquentiellement des programmes qui sont des suites d'instructions élémentaires
  • les données que peuvent manipuler ces instructions appartiennent à quelques types bien connus :

(nombres entiers ou réels, caractères, adresses, et c'est à peu près tout...)

5

<!-- Slide number: 6 -->

Ceci convenait toutefois très bien aux premières applications des calculateurs :

  • il s'agissait en effet d'effectuer des suites de calculs longues et répétitives
  • pour établir des tables numériques , calculs numériques, etc …

6

<!-- Slide number: 7 -->

Les programmes de l'époque ne pouvaient guère être compliqués

  • en raison de la très faible capacité des mémoires disponibles

7

<!-- Slide number: 8 -->

Cette capacité augmentant naturellement au fil des années, on s'est avisé qu'il pouvait être intéressant :

d'écrire des programmes en utilisant des noms mnémotechniques pour chacune des instructions de la machine : naissance du langage d'assemblage

(Ainsi les programmes sont plus facile à écrire et surtout à relire)

d'utiliser des langages de programmation indépendants de la machine utilisée : langages évolués

(chaque instruction en langage évolué se traduisant en une petite séquence d'instructions dans le langage de la machine)

8

<!-- Slide number: 9 -->

On remarque que cette évolution préserve deux traits fondamentaux de l'informatique des origines :

l'aspect séquentiel des programmes

la notion d'affectation

ce qu'on appelle «programmation impérative» puisqu'il s'agit de faire exécuter une suite d'ordres par une machine bête mais disciplinée

9

<!-- Slide number: 10 -->

Ne pouvant dire à la machine «c'est votre problème débrouillez-vous»

  • le programmeur doit décrire la suite exhaustive des actions à exécuter

Vous connaissez tous l'aspect fastidieux de ce genre d'activité

  • qui demande par ailleurs une formation particulière (songez à vos premiers démêlés avec l'algorithmique)

10

<!-- Slide number: 11 -->

La « crise » du logiciel

Comment :

gérer la taille et la complexité des programmes modernes?

réduire le temps et le coût du développement logiciel ?

accroître notre confiance qu’un programme fonctionne correctement ?

11

<!-- Slide number: 12 -->

Approche pour résoudre la crise

Créer des langages de programmation qui :

permettent que les programmes soient écrits clairement

à un haut niveau d’abstraction

supportent des composantes logicielles réutilisables

encouragent le recours à la vérification formelle

permettent un prototypage rapide

offrent des outils puissants pour résoudre les problèmes

Les langages de programmation fonctionnels (PF) :

boite à outils particulièrement élégante permettant de

réaliser tous ces objectifs

12

<!-- Slide number: 13 -->

II- Programmation Impérative/Déclarative

La plupart des langages de programmation (il en existe plusieurs milliers) relèvent de la susdite Programmation Impérative

Il existe cependant une autre catégorie : les langages déclaratifs (LD) ?

13

<!-- Slide number: 14 -->

Dans un langage déclaratif l'activité de programmation consiste essentiellement :

  • à décrire le rapport qui existe entre les données et les résultats que l'on veut obtenir
  • plutôt que la séquence de traitements qui mène des unes aux autres

(évidemment ceci représente un idéal...)

Publicité

14

<!-- Slide number: 15 -->

Deux approches sont fréquemment utilisées dans les LD :

Programmation Fonctionnelle :

Le but d'un traitement informatique est de calculer des résultats à partir de données

Pourquoi ne pas assimiler un programme à une fonction qui à des données associe un résultat ?

un traitement complexe s'obtiendra en combinant plusieurs fonctions intermédiaires (correspondant à des sous-traitements)

Exemples : Ml, Ocamel, Haskell, Sheme, Hope, Lisp, ...

Programmation Logique :

On décrit par une formule logique la relation qui existe entre les données et les résultats

Exemples : Prolog, Qlog, …

15

<!-- Slide number: 16 -->

III- Historique de la PF

16

<!-- Slide number: 17 -->

1930s

Alonzo Church développe le lambda-calcul, une théorie des fonctions, simple mais puissante

![](Picture6.jpg)

17

<!-- Slide number: 18 -->

1930s

Haskell B. Curry développe la logique combinatoire, qui deviendra le moteur des langages fonctionnels

![](Picture4.jpg)

18

<!-- Slide number: 19 -->

1950s

John McCarthy développe Lisp, le premier langage fonctionnel, sous l’influence du lambda-calcul, mais en conservant l’affectation des variables

![](ContentPlaceholder5.jpg)

19

<!-- Slide number: 20 -->

1960s

Peter Landin développe ISWIM 1, le premier langage de programmation fonctionnel pur, fortement basé sur le lambda-calcul, sans affectation de variables

1. De : « If you See What I Mean »

![](Picture6.jpg)

20

<!-- Slide number: 21 -->

1970s

John Backus développe FP, un langage de programmation fonctionnel qui pose l’accent sur les fonctions d’ordre supérieur et sur l’intégration avec le raisonnement sur les programmes

![](Picture4.jpg)

21

<!-- Slide number: 22 -->

1970s

Robin Milner et autres développent ML, le premier langage fonctionnel moderne, qui introduit l’inférence de type et les types polymorphes

![](Picture4.jpg)

22

<!-- Slide number: 23 -->

1970s - 1980s

David Turner développe un nombre de langages fonctionnels paresseux (lazy), qui culminent dans le système Miranda

![](Picture4.jpg)

23

<!-- Slide number: 24 -->

1987

Un comité international de chercheurs débute le développement de Haskell, un langage fonctionnel paresseux standard

![](Picture4.jpg)

24

<!-- Slide number: 25 -->

2003

Le comité publie le rapport Haskell 98, qui définit une version stable du langage

![](Picture4.jpg)

25

<!-- Slide number: 26 -->

Les héros français

1985

Gérard Huet et son équipe à l’INRIA développent CAM, une version du langage ML destiné à s’intégrer avec le système Coq

Autres intervenant dans le chemin CAM->CAML->OCAML : Xavier Leroy, Didier Rémy, Jérôme Vouillon

![](Picture4.jpg)

26

<!-- Slide number: 27 -->

IV- Paradigmes de Programmation

A- Programmation Impérative

En programmation impérative le programme est une suite d’instructions qui modifient l’état de la mémoire centrale

On peut représenter un programme par une machine d'états qui représente les états successifs de la mémoire

27

<!-- Slide number: 28 -->

L'implémentation de la quasi totalité des processeurs qui équipent les ordinateurs est de nature impérative

Les processeurs sont faits pour exécuter des instructions élémentaires exécutables par le processeur et modifiant l’état de la mémoire

28

<!-- Slide number: 29 -->

Ce type de programmation nécessite pour le programmeur de connaître à tout instant l'état de la mémoire

La plupart des langages de haut niveau suivent le paradigme impératif même s’ils utilisent des variables et des opérations plus complexes que les instructions élémentaires

• Fortran, C, Pascal, Java …

29

<!-- Slide number: 30 -->

Les langages de haut niveau intègrent également de nombreuses techniques destinées à réduire le nombre de variables à gérer :

Variables dont la portée se limite à la procédure dans laquelle elles ont été définies et qui sont automatiquement libérées à la sortie de la procédure

Encapsulation des données, à l'origine de la programmation structurée, et la programmation orienté objet

30

<!-- Slide number: 31 -->

B- Programmation Fonctionnelle

Publicité

Le paradigme fonctionnel n'utilise pas de machine d'états pour décrire un programme, mais un emboîtement de fonctions

Le programmeur ne se préoccupe pas de l’état de la mémoire

31

<!-- Slide number: 32 -->

Il est en théorie impossible d’assigner une valeur à une variable

Un programme est donc une application, au sens mathématique, qui ne donne qu'un seul résultat pour chaque ensemble de valeurs en entrée

→ Exécution d’un programme = Evaluation d’une fonction

32

<!-- Slide number: 33 -->

Cependant, pour des raisons d'efficacité, la plupart des langages fonctionnels autorisent l’utilisation de variables

→ Langages fonctionnels impurs

A noter également que beaucoup de langages impératifs permettent plus ou moins d’écrire dans un style fonctionnel

33

<!-- Slide number: 34 -->

Les langages fonctionnels emploient des types et des structures de données de haut niveau comme les listes extensibles

Il est ainsi généralement possible de réaliser facilement des opérations comme la concaténation de listes

Les langages fonctionnels font un large usage de la récursivité

34

<!-- Slide number: 35 -->

La programmation fonctionnelle offre des avantages sans équivalent en impératif

Malgré cela, elle reste peu utilisée en dehors du milieu universitaire et des lobbyistes

déficit en outils et en bibliothèques de qualité commerciale

manque de programmeurs formés

35

<!-- Slide number: 36 -->

Quelques langages fonctionnels :

Lisp (le premier)

Scheme, Caml, Haskell

XSLT (dédié au traitement XML)

Rebol (celui que je préfère)

36

<!-- Slide number: 37 -->

C- Programmation Logique

Fondée sur la logique mathématique

Programmation déclarative

On déclare des informations avérées:– le programme appelé aussi la base de connaissances

On déclare une requête (appelée aussi un but) – Le moteur Prolog tente de répondre à la requête en se servant des informations contenues dans la base de connaissance

37

<!-- Slide number: 38 -->

Utilisée en Intelligence Artificielle

La programmation logique se confond avec le langage Prolog !

38

<!-- Slide number: 39 -->

Exemple: Factorielle (impératif)

Programme C

int fac(int n) { int i; int res = 1; if(n==0) return 1; else for(i= 1; i <= n; i++) res *= i; return res; };int reponse = fac(3); printf("factorielle 3 vaut %d", reponse);

39

<!-- Slide number: 40 -->

Exemple: Factorielle (fonctionnel)

Programme LISP

(defun factorial (n) (if (<= n 1) 1 (* n (factorial (- n 1)))))(factorial 3)

Notez,

Aucune variable utilisée

L’appel récursif à la fonction factorial

L’emboitement des fonctions – la fonction <= emboitée dans la fonction if– la fonction emboitée dans la fonction if– la fonction factorial emboitée dans la fonction – la fonction - emboitée dans la fonction factorial

40

<!-- Slide number: 41 -->

Exemple: Factorielle (logique)

Base de connaissances Prolog

factoriel(0,1)

factoriel(X,Y) :-- X1 is X–1 et factoriel(X1,Z) et Y is Z*X

Requêtes Prolog

?- factoriel(3,6)true

?- factoriel(3,Y)Y = 6

41

<!-- Slide number: 42 -->

Donc

Deux différents paradigmes :

Principalement :

Programmation impérative

Procédurale (C, Fortran, …)

Objet (Java, C++, C#, …)

Programmation déclarative

Fonctionnelle (Haskell, … )

Logique (Prolog, …)

Et bien d'autres...

42

<!-- Slide number: 43 -->

Programmation impérative

Procédurale

Fonctions

Structures

… et c'est tout

Objet

Classes

Méthodes

Fonctions libres

→ On modifie des variables, tout le temps !

→ On spécifie chaque instruction !

Publicité

43

<!-- Slide number: 44 -->

Programmation déclarative

Fonctionnelle

Fonctions, fonctions, fonctions

Facilités pour les faire interagir

Pas d'instructions, que des expressions

Logique

Prédicats, prédicats, prédicats

Moteur d'inférence logique

44

<!-- Slide number: 45 -->

Qu’est ce qu’un langage fonctionnel ?

Plusieurs avis, pas de définition précise, mais (en gros) :

La programmation fonctionnelle est un

style de programmation

où l’étape élémentaire du calcul est

l’application d’une fonction à ses arguments

Un langage est fonctionnel s’il supporte et encourage ce style fonctionnel

45

<!-- Slide number: 46 -->

Exemple

Sommation des entiers de 1 à 5 en Java :

total = 0;

for (i = 1; i <= 5; ++i)

total = total+i;

Le calcul repose sur :

l’affectation des variables

les boucles

46

<!-- Slide number: 47 -->

Exemple

La fonction somme en Haskell :

somme :: [Int] -> Int

somme [] = 0

somme (x:xs) = x + somme xs

Sommation des entiers de 1 à 5 en Haskell :

1 + 2 + somme (3:4:5:[]) =

1 + 2 + 3 + somme (4:5:[]) =

1 + 2 + 3 + 4 + somme (5:[]) =

1 + 2 + 3 + 4 + 5 + somme [] =

1 + 2 + 3 + 4 + 5 + 0 =

15

47

<!-- Slide number: 48 -->

La méthode de calcul repose sur :

l’application d’une fonction à ses arguments

la récursion

l’évaluation d’une expression vers une valeur

48

<!-- Slide number: 49 -->

Essence de la PF

On peut définir, mélanger, composer […] des fonctions

wc_linenb filename = length . lines . readFile filename add_n_to_list n list = map (\x → x+n) list

Selon les langages, on peut définir des types de données algébriques

data Direction = Up | Down | Left | Right data Number = Positive Int | Zero | Negative Int

49

<!-- Slide number: 50 -->

On peut se servir de ces types efficacement :

pattern matching

is_positive (Positive n) = True

is_positive (Zero) = True

is_positive (Negative n) = False

On a les clôtures (transparence référentielle) :

x = 4

f y = x+y – c'est une fonction

x = 5

f 1 – on appelle la fonction

cela retourne … 5, et pas 6

50

<!-- Slide number: 51 -->

Essence de la PF

Finie la gestion de la mémoire

On applique des fonctions plutôt que de modifier des variables

51

<!-- Slide number: 52 -->

V- Intelligence Artificielle et PF

Dès la fin des années 50

→ un certain nombre d'équipes ont mené des recherches importantes dans le domaine baptisé communément Intelligence Artificielle (IA)

-(en particulier des programmes de démonstration automatique ; des programmes de jeu, etc... )

Qu'est-ce que l'IA ?

  • C'est de faire faire par une machine des choses qui nous paraissent relever de l'Intelligence humaine

52

<!-- Slide number: 53 -->

Une des particularités de la programmation en IA est la nécessité de manipuler facilement des symboles et des listes de symboles

plutôt que des nombres ou des chaînes de caractères :

→ ce qu'on appelle la Programmation Symbolique

53

<!-- Slide number: 54 -->

Les langages de l'époque n'offrant pas ce genre de facilités

Publicité

→ un chercheur du MIT, John MacCarthy s'est lancé vers 56-58 dans la définition d'un langage ad hoc baptisé LISP

(LISt Processing language)

54

<!-- Slide number: 55 -->

Depuis LISP 1.5 (la première version largement diffusée)

plusieurs centaines d'implémentations de «dialectes Lisp» ont été développées

en effet l'écriture d'un interpréteur LISP n'est pas un travail énorme (quelques milliers d'instructions)

  • comparativement au développement d'un compilateur pour un langage classique (plusieurs dizaines de milliers d'instructions)

→ d'où l'éclosion (années 60-70) de centaines de versions différentes

(presque autant que d'utilisateurs, disent les mauvaises langues !)

55

<!-- Slide number: 56 -->

Ce phénomène est également du au milieu Lispien

les chercheurs en IA étaient de fait d'excellents programmeurs car :

  • peu liés par des contraintes extérieures de délais
  • dont le travail consistait d'une part à trouver des idées
  • d'autre part à les tester en écrivant des programmes prototypes qui seront entièrement réécrits si l'idée s'avère fructueuse
  • et finiront au panier dans le cas contraire

(le plus fréquent)

56

<!-- Slide number: 57 -->

VI- Langages de PF

57

<!-- Slide number: 58 -->

la famille Lisp

L'engouement pour l'IA a favorisé la tendance à la standardisation du langage LISP

Il est évidemment plus économique de disposer du même langage sur toutes les machines sur lesquelles on désire porter un logiciel commercial

Parmi les LISP citons :

MACLISP développé au MIT pour la réalisation du système MACSYMA (calcul formel)

58

<!-- Slide number: 59 -->

FRANZ LISP qui, bien qu'écrit en C par des étudiants (Berkeley), fonctionne malgré tout sur la plupart des systèmes UNIX

LE_LISP développé à l'INRIA par Jérôme CHAILLOUX

59

<!-- Slide number: 60 -->

COMMON LISP, qui est (comme son nom l'indique) une proposition de standard d'origine américaine

Et enfin SCHEME, version modernisée et plus «propre» de ce langage

Il est à noter que certains logiciels (par exemple l'éditeur de textes Emacs, ou logiciel de CAO AutoCad) contiennent un petit interpréteur Lisp

  • qui permet à l'utilisateur d'écrire des programmes qui étendent les possibilités de base du logiciel

Lisp → vieux, puissant mais laborieux,

communauté assez restreinte

60

<!-- Slide number: 61 -->

D’autres Langages

Langages de PF populaires :

Objective Caml : pas tellement vieux, rapide, autorise l'impératif, communauté correcte, nombre respectable d'outils & bibliothèques

Haskell : pas très vieux, purement fonctionnel, communauté hyperactive, énormément d'outils & bibliothèques !

Erlang, Clojure, Scheme, F#, …

→ généralement opensource, comités pour l'évolution, projets communautaires, ...

61

<!-- Slide number: 62 -->

#

XSLT (dédié au traitement XML)

Rebol

ISWIM

FP

ML

CAM (Camel, OCamel, …)

Hope

62

<!-- Slide number: 63 -->

Et dans la pratique …?

Souvent interpréteur intéractif (Ocaml, Haskell notamment)

Souvent compilateur vers bytecode, donc avec une VM – souvent munie d'un garbage collector

Quelques compilateurs vers du code natif pour les performances

Souvent une Foreign Function Interface pour appeler des fonctions C depuis le langage directement

63

<!-- Slide number: 64 -->

Et dans la pratique … ?

Soit statiquement typé (OCaml, Haskell), soit dynamiquement typé (Lisp, Scheme)

On fait ressortir autant de choses que possible dans les types (Maybe, …)

Les types sont généralement inférés automatiquement

Une fois que le code est testé, chances infimes que “cela plante en route”

La récursion remplace les boucles classiques

(for, while & co), et l'on a des primitives de récursions (“schémas” de récursion qui permettent presque de tout faire)

64

<!-- Slide number: 65 -->

Avantages

Le compilateur en PF facilite beaucoup le travail

Une fois la compilation passée, peu de risques de disfonctionnement

Un programme fonctionnel est presque un ensemble de phrases, on exprime ce qu'on veut et pas chaque étape → plus proche des langues humaines

Limiter voire interdire les effets de bord limite les surprises à l'exécution : 2 appels avec les mêmes arguments renvoient la même chose

→ et bien d'autres avec le temps...

65

<!-- Slide number: 66 -->

Inconvénients

Très (très très très) différent des langages impératifs, qui sont les plus utilisés & connus

Des fois, les effets de bord, ça aide …

Manque de bibliothèques / outils pour “rivaliser” avec des grosses technos (Java, .NET, etc)

Trop peu de boîtes qui utilisent les langages fonctionnels (même si dedans il y a Intel, MS, IBM, des boîtes de finances, l'aéronautique, aérospatial, ...)

66

Programmation Fonctionnelle et Origines des Langages

Programming, Functional Programming · course

Voir tous les documents en programmation

<!-- Slide number: 1 -->

Programmation Fonctionnelle

Chapitre I :

Introduction

BEJI Faryel

1

<!-- Slide number: 2 -->

ML, Lisp, and Haskell are the only programming languages that I've seen where one spends more time thinking than typing.    Philip Greenspun

![](Picture5.jpg)

![](Picture3.jpg)

![](Picture5.jpg)

![](Picture4.jpg)

2

<!-- Slide number: 3 -->

Plan

I- Avant Propos

II- Programmation Impérative /Déclarative

III-Historique de la PF

IV- Paradigmes de Programmation

V- Intelligence Artificielle et PF

VI- Langages de PF

3

<!-- Slide number: 4 -->

I- Avant Propos

Souvent présentés comme le summum de la technologie, les ordinateurs sont en fait des machines assez simples (dans leur principe), fabriquées à partir de quelques types de circuits élémentaires :

registres, mémoires, additionneurs, décodeurs etc...

4

<!-- Slide number: 5 -->

Ces machines fonctionnent de la manière suivante :

  • elles exécutent séquentiellement des programmes qui sont des suites d'instructions élémentaires
  • les données que peuvent manipuler ces instructions appartiennent à quelques types bien connus :

(nombres entiers ou réels, caractères, adresses, et c'est à peu près tout...)

5

<!-- Slide number: 6 -->

Ceci convenait toutefois très bien aux premières applications des calculateurs :

  • il s'agissait en effet d'effectuer des suites de calculs longues et répétitives
  • pour établir des tables numériques , calculs numériques, etc …

6

<!-- Slide number: 7 -->

Les programmes de l'époque ne pouvaient guère être compliqués

  • en raison de la très faible capacité des mémoires disponibles

7

<!-- Slide number: 8 -->

Cette capacité augmentant naturellement au fil des années, on s'est avisé qu'il pouvait être intéressant :

d'écrire des programmes en utilisant des noms mnémotechniques pour chacune des instructions de la machine : naissance du langage d'assemblage

(Ainsi les programmes sont plus facile à écrire et surtout à relire)

d'utiliser des langages de programmation indépendants de la machine utilisée : langages évolués

(chaque instruction en langage évolué se traduisant en une petite séquence d'instructions dans le langage de la machine)

8

<!-- Slide number: 9 -->

On remarque que cette évolution préserve deux traits fondamentaux de l'informatique des origines :

l'aspect séquentiel des programmes

la notion d'affectation

ce qu'on appelle «programmation impérative» puisqu'il s'agit de faire exécuter une suite d'ordres par une machine bête mais disciplinée

9

<!-- Slide number: 10 -->

Ne pouvant dire à la machine «c'est votre problème débrouillez-vous»

  • le programmeur doit décrire la suite exhaustive des actions à exécuter

Vous connaissez tous l'aspect fastidieux de ce genre d'activité

  • qui demande par ailleurs une formation particulière (songez à vos premiers démêlés avec l'algorithmique)

10

<!-- Slide number: 11 -->

La « crise » du logiciel

Comment :

gérer la taille et la complexité des programmes modernes?

réduire le temps et le coût du développement logiciel ?

accroître notre confiance qu’un programme fonctionne correctement ?

11

<!-- Slide number: 12 -->

Approche pour résoudre la crise

Créer des langages de programmation qui :

permettent que les programmes soient écrits clairement

à un haut niveau d’abstraction

supportent des composantes logicielles réutilisables

encouragent le recours à la vérification formelle

permettent un prototypage rapide

offrent des outils puissants pour résoudre les problèmes

Les langages de programmation fonctionnels (PF) :

boite à outils particulièrement élégante permettant de

réaliser tous ces objectifs

12

<!-- Slide number: 13 -->

II- Programmation Impérative/Déclarative

La plupart des langages de programmation (il en existe plusieurs milliers) relèvent de la susdite Programmation Impérative

Il existe cependant une autre catégorie : les langages déclaratifs (LD) ?

13

<!-- Slide number: 14 -->

Dans un langage déclaratif l'activité de programmation consiste essentiellement :

  • à décrire le rapport qui existe entre les données et les résultats que l'on veut obtenir
  • plutôt que la séquence de traitements qui mène des unes aux autres

(évidemment ceci représente un idéal...)

Publicité

14

<!-- Slide number: 15 -->

Deux approches sont fréquemment utilisées dans les LD :

Programmation Fonctionnelle :

Le but d'un traitement informatique est de calculer des résultats à partir de données

Pourquoi ne pas assimiler un programme à une fonction qui à des données associe un résultat ?

un traitement complexe s'obtiendra en combinant plusieurs fonctions intermédiaires (correspondant à des sous-traitements)

Exemples : Ml, Ocamel, Haskell, Sheme, Hope, Lisp, ...

Programmation Logique :

On décrit par une formule logique la relation qui existe entre les données et les résultats

Exemples : Prolog, Qlog, …

15

<!-- Slide number: 16 -->

III- Historique de la PF

16

<!-- Slide number: 17 -->

1930s

Alonzo Church développe le lambda-calcul, une théorie des fonctions, simple mais puissante

![](Picture6.jpg)

17

<!-- Slide number: 18 -->

1930s

Haskell B. Curry développe la logique combinatoire, qui deviendra le moteur des langages fonctionnels

![](Picture4.jpg)

18

<!-- Slide number: 19 -->

1950s

John McCarthy développe Lisp, le premier langage fonctionnel, sous l’influence du lambda-calcul, mais en conservant l’affectation des variables

![](ContentPlaceholder5.jpg)

19

<!-- Slide number: 20 -->

1960s

Peter Landin développe ISWIM 1, le premier langage de programmation fonctionnel pur, fortement basé sur le lambda-calcul, sans affectation de variables

1. De : « If you See What I Mean »

![](Picture6.jpg)

20

<!-- Slide number: 21 -->

1970s

John Backus développe FP, un langage de programmation fonctionnel qui pose l’accent sur les fonctions d’ordre supérieur et sur l’intégration avec le raisonnement sur les programmes

![](Picture4.jpg)

21

<!-- Slide number: 22 -->

1970s

Robin Milner et autres développent ML, le premier langage fonctionnel moderne, qui introduit l’inférence de type et les types polymorphes

![](Picture4.jpg)

22

<!-- Slide number: 23 -->

1970s - 1980s

David Turner développe un nombre de langages fonctionnels paresseux (lazy), qui culminent dans le système Miranda

![](Picture4.jpg)

23

<!-- Slide number: 24 -->

1987

Un comité international de chercheurs débute le développement de Haskell, un langage fonctionnel paresseux standard

![](Picture4.jpg)

24

<!-- Slide number: 25 -->

2003

Le comité publie le rapport Haskell 98, qui définit une version stable du langage

![](Picture4.jpg)

25

<!-- Slide number: 26 -->

Les héros français

1985

Gérard Huet et son équipe à l’INRIA développent CAM, une version du langage ML destiné à s’intégrer avec le système Coq

Autres intervenant dans le chemin CAM->CAML->OCAML : Xavier Leroy, Didier Rémy, Jérôme Vouillon

![](Picture4.jpg)

26

<!-- Slide number: 27 -->

IV- Paradigmes de Programmation

A- Programmation Impérative

En programmation impérative le programme est une suite d’instructions qui modifient l’état de la mémoire centrale

On peut représenter un programme par une machine d'états qui représente les états successifs de la mémoire

27

<!-- Slide number: 28 -->

L'implémentation de la quasi totalité des processeurs qui équipent les ordinateurs est de nature impérative

Les processeurs sont faits pour exécuter des instructions élémentaires exécutables par le processeur et modifiant l’état de la mémoire

28

<!-- Slide number: 29 -->

Ce type de programmation nécessite pour le programmeur de connaître à tout instant l'état de la mémoire

La plupart des langages de haut niveau suivent le paradigme impératif même s’ils utilisent des variables et des opérations plus complexes que les instructions élémentaires

• Fortran, C, Pascal, Java …

29

<!-- Slide number: 30 -->

Les langages de haut niveau intègrent également de nombreuses techniques destinées à réduire le nombre de variables à gérer :

Variables dont la portée se limite à la procédure dans laquelle elles ont été définies et qui sont automatiquement libérées à la sortie de la procédure

Encapsulation des données, à l'origine de la programmation structurée, et la programmation orienté objet

30

<!-- Slide number: 31 -->

B- Programmation Fonctionnelle

Publicité

Le paradigme fonctionnel n'utilise pas de machine d'états pour décrire un programme, mais un emboîtement de fonctions

Le programmeur ne se préoccupe pas de l’état de la mémoire

31

<!-- Slide number: 32 -->

Il est en théorie impossible d’assigner une valeur à une variable

Un programme est donc une application, au sens mathématique, qui ne donne qu'un seul résultat pour chaque ensemble de valeurs en entrée

→ Exécution d’un programme = Evaluation d’une fonction

32

<!-- Slide number: 33 -->

Cependant, pour des raisons d'efficacité, la plupart des langages fonctionnels autorisent l’utilisation de variables

→ Langages fonctionnels impurs

A noter également que beaucoup de langages impératifs permettent plus ou moins d’écrire dans un style fonctionnel

33

<!-- Slide number: 34 -->

Les langages fonctionnels emploient des types et des structures de données de haut niveau comme les listes extensibles

Il est ainsi généralement possible de réaliser facilement des opérations comme la concaténation de listes

Les langages fonctionnels font un large usage de la récursivité

34

<!-- Slide number: 35 -->

La programmation fonctionnelle offre des avantages sans équivalent en impératif

Malgré cela, elle reste peu utilisée en dehors du milieu universitaire et des lobbyistes

déficit en outils et en bibliothèques de qualité commerciale

manque de programmeurs formés

35

<!-- Slide number: 36 -->

Quelques langages fonctionnels :

Lisp (le premier)

Scheme, Caml, Haskell

XSLT (dédié au traitement XML)

Rebol (celui que je préfère)

36

<!-- Slide number: 37 -->

C- Programmation Logique

Fondée sur la logique mathématique

Programmation déclarative

On déclare des informations avérées:– le programme appelé aussi la base de connaissances

On déclare une requête (appelée aussi un but) – Le moteur Prolog tente de répondre à la requête en se servant des informations contenues dans la base de connaissance

37

<!-- Slide number: 38 -->

Utilisée en Intelligence Artificielle

La programmation logique se confond avec le langage Prolog !

38

<!-- Slide number: 39 -->

Exemple: Factorielle (impératif)

Programme C

int fac(int n) { int i; int res = 1; if(n==0) return 1; else for(i= 1; i <= n; i++) res *= i; return res; };int reponse = fac(3); printf("factorielle 3 vaut %d", reponse);

39

<!-- Slide number: 40 -->

Exemple: Factorielle (fonctionnel)

Programme LISP

(defun factorial (n) (if (<= n 1) 1 (* n (factorial (- n 1)))))(factorial 3)

Notez,

Aucune variable utilisée

L’appel récursif à la fonction factorial

L’emboitement des fonctions – la fonction <= emboitée dans la fonction if– la fonction emboitée dans la fonction if– la fonction factorial emboitée dans la fonction – la fonction - emboitée dans la fonction factorial

40

<!-- Slide number: 41 -->

Exemple: Factorielle (logique)

Base de connaissances Prolog

factoriel(0,1)

factoriel(X,Y) :-- X1 is X–1 et factoriel(X1,Z) et Y is Z*X

Requêtes Prolog

?- factoriel(3,6)true

?- factoriel(3,Y)Y = 6

41

<!-- Slide number: 42 -->

Donc

Deux différents paradigmes :

Principalement :

Programmation impérative

Procédurale (C, Fortran, …)

Objet (Java, C++, C#, …)

Programmation déclarative

Fonctionnelle (Haskell, … )

Logique (Prolog, …)

Et bien d'autres...

42

<!-- Slide number: 43 -->

Programmation impérative

Procédurale

Fonctions

Structures

… et c'est tout

Objet

Classes

Méthodes

Fonctions libres

→ On modifie des variables, tout le temps !

→ On spécifie chaque instruction !

Publicité

43

<!-- Slide number: 44 -->

Programmation déclarative

Fonctionnelle

Fonctions, fonctions, fonctions

Facilités pour les faire interagir

Pas d'instructions, que des expressions

Logique

Prédicats, prédicats, prédicats

Moteur d'inférence logique

44

<!-- Slide number: 45 -->

Qu’est ce qu’un langage fonctionnel ?

Plusieurs avis, pas de définition précise, mais (en gros) :

La programmation fonctionnelle est un

style de programmation

où l’étape élémentaire du calcul est

l’application d’une fonction à ses arguments

Un langage est fonctionnel s’il supporte et encourage ce style fonctionnel

45

<!-- Slide number: 46 -->

Exemple

Sommation des entiers de 1 à 5 en Java :

total = 0;

for (i = 1; i <= 5; ++i)

total = total+i;

Le calcul repose sur :

l’affectation des variables

les boucles

46

<!-- Slide number: 47 -->

Exemple

La fonction somme en Haskell :

somme :: [Int] -> Int

somme [] = 0

somme (x:xs) = x + somme xs

Sommation des entiers de 1 à 5 en Haskell :

1 + 2 + somme (3:4:5:[]) =

1 + 2 + 3 + somme (4:5:[]) =

1 + 2 + 3 + 4 + somme (5:[]) =

1 + 2 + 3 + 4 + 5 + somme [] =

1 + 2 + 3 + 4 + 5 + 0 =

15

47

<!-- Slide number: 48 -->

La méthode de calcul repose sur :

l’application d’une fonction à ses arguments

la récursion

l’évaluation d’une expression vers une valeur

48

<!-- Slide number: 49 -->

Essence de la PF

On peut définir, mélanger, composer […] des fonctions

wc_linenb filename = length . lines . readFile filename add_n_to_list n list = map (\x → x+n) list

Selon les langages, on peut définir des types de données algébriques

data Direction = Up | Down | Left | Right data Number = Positive Int | Zero | Negative Int

49

<!-- Slide number: 50 -->

On peut se servir de ces types efficacement :

pattern matching

is_positive (Positive n) = True

is_positive (Zero) = True

is_positive (Negative n) = False

On a les clôtures (transparence référentielle) :

x = 4

f y = x+y – c'est une fonction

x = 5

f 1 – on appelle la fonction

cela retourne … 5, et pas 6

50

<!-- Slide number: 51 -->

Essence de la PF

Finie la gestion de la mémoire

On applique des fonctions plutôt que de modifier des variables

51

<!-- Slide number: 52 -->

V- Intelligence Artificielle et PF

Dès la fin des années 50

→ un certain nombre d'équipes ont mené des recherches importantes dans le domaine baptisé communément Intelligence Artificielle (IA)

-(en particulier des programmes de démonstration automatique ; des programmes de jeu, etc... )

Qu'est-ce que l'IA ?

  • C'est de faire faire par une machine des choses qui nous paraissent relever de l'Intelligence humaine

52

<!-- Slide number: 53 -->

Une des particularités de la programmation en IA est la nécessité de manipuler facilement des symboles et des listes de symboles

plutôt que des nombres ou des chaînes de caractères :

→ ce qu'on appelle la Programmation Symbolique

53

<!-- Slide number: 54 -->

Les langages de l'époque n'offrant pas ce genre de facilités

Publicité

→ un chercheur du MIT, John MacCarthy s'est lancé vers 56-58 dans la définition d'un langage ad hoc baptisé LISP

(LISt Processing language)

54

<!-- Slide number: 55 -->

Depuis LISP 1.5 (la première version largement diffusée)

plusieurs centaines d'implémentations de «dialectes Lisp» ont été développées

en effet l'écriture d'un interpréteur LISP n'est pas un travail énorme (quelques milliers d'instructions)

  • comparativement au développement d'un compilateur pour un langage classique (plusieurs dizaines de milliers d'instructions)

→ d'où l'éclosion (années 60-70) de centaines de versions différentes

(presque autant que d'utilisateurs, disent les mauvaises langues !)

55

<!-- Slide number: 56 -->

Ce phénomène est également du au milieu Lispien

les chercheurs en IA étaient de fait d'excellents programmeurs car :

  • peu liés par des contraintes extérieures de délais
  • dont le travail consistait d'une part à trouver des idées
  • d'autre part à les tester en écrivant des programmes prototypes qui seront entièrement réécrits si l'idée s'avère fructueuse
  • et finiront au panier dans le cas contraire

(le plus fréquent)

56

<!-- Slide number: 57 -->

VI- Langages de PF

57

<!-- Slide number: 58 -->

la famille Lisp

L'engouement pour l'IA a favorisé la tendance à la standardisation du langage LISP

Il est évidemment plus économique de disposer du même langage sur toutes les machines sur lesquelles on désire porter un logiciel commercial

Parmi les LISP citons :

MACLISP développé au MIT pour la réalisation du système MACSYMA (calcul formel)

58

<!-- Slide number: 59 -->

FRANZ LISP qui, bien qu'écrit en C par des étudiants (Berkeley), fonctionne malgré tout sur la plupart des systèmes UNIX

LE_LISP développé à l'INRIA par Jérôme CHAILLOUX

59

<!-- Slide number: 60 -->

COMMON LISP, qui est (comme son nom l'indique) une proposition de standard d'origine américaine

Et enfin SCHEME, version modernisée et plus «propre» de ce langage

Il est à noter que certains logiciels (par exemple l'éditeur de textes Emacs, ou logiciel de CAO AutoCad) contiennent un petit interpréteur Lisp

  • qui permet à l'utilisateur d'écrire des programmes qui étendent les possibilités de base du logiciel

Lisp → vieux, puissant mais laborieux,

communauté assez restreinte

60

<!-- Slide number: 61 -->

D’autres Langages

Langages de PF populaires :

Objective Caml : pas tellement vieux, rapide, autorise l'impératif, communauté correcte, nombre respectable d'outils & bibliothèques

Haskell : pas très vieux, purement fonctionnel, communauté hyperactive, énormément d'outils & bibliothèques !

Erlang, Clojure, Scheme, F#, …

→ généralement opensource, comités pour l'évolution, projets communautaires, ...

61

<!-- Slide number: 62 -->

#

XSLT (dédié au traitement XML)

Rebol

ISWIM

FP

ML

CAM (Camel, OCamel, …)

Hope

62

<!-- Slide number: 63 -->

Et dans la pratique …?

Souvent interpréteur intéractif (Ocaml, Haskell notamment)

Souvent compilateur vers bytecode, donc avec une VM – souvent munie d'un garbage collector

Quelques compilateurs vers du code natif pour les performances

Souvent une Foreign Function Interface pour appeler des fonctions C depuis le langage directement

63

<!-- Slide number: 64 -->

Et dans la pratique … ?

Soit statiquement typé (OCaml, Haskell), soit dynamiquement typé (Lisp, Scheme)

On fait ressortir autant de choses que possible dans les types (Maybe, …)

Les types sont généralement inférés automatiquement

Une fois que le code est testé, chances infimes que “cela plante en route”

La récursion remplace les boucles classiques

(for, while & co), et l'on a des primitives de récursions (“schémas” de récursion qui permettent presque de tout faire)

64

<!-- Slide number: 65 -->

Avantages

Le compilateur en PF facilite beaucoup le travail

Une fois la compilation passée, peu de risques de disfonctionnement

Un programme fonctionnel est presque un ensemble de phrases, on exprime ce qu'on veut et pas chaque étape → plus proche des langues humaines

Limiter voire interdire les effets de bord limite les surprises à l'exécution : 2 appels avec les mêmes arguments renvoient la même chose

→ et bien d'autres avec le temps...

65

<!-- Slide number: 66 -->

Inconvénients

Très (très très très) différent des langages impératifs, qui sont les plus utilisés & connus

Des fois, les effets de bord, ça aide …

Manque de bibliothèques / outils pour “rivaliser” avec des grosses technos (Java, .NET, etc)

Trop peu de boîtes qui utilisent les langages fonctionnels (même si dedans il y a Intel, MS, IBM, des boîtes de finances, l'aéronautique, aérospatial, ...)

66