Aller au contenu

Introduction

Vous avez déjà utilisé au moins deux paradigmes de programmation :

  • Le programmation impérative

C’est la programmation à laquelle vous étiez habitué(e)s avant de débuter la programmation orientée objet.

Vous écriviez des instructions à la suite des autres :

def somme(limite):
    s = 0
    for i in range(limite):
        s += i
    return s

somme(10)
  • La programmation orientée objet

Nous allons étudier un nouveau paradigme : le paradigme fonctionnel

Le paradigme fonctionnel

Dans une fonction mathématique,

Le paradigme fonctionnel souhaite éviter les effets de bords, c'est à dire ne pas modifier la valeur associée à une variable suite à une valeur extérieure à la fonction.

L'idée est de rapprocher un maximum des fonctions mathématiques, où on compose différentes fonctions pour lesquelles l'image associée à un antécédent donné ne va pas changer au cours du temps.

Les variables sont en fait des constantes en programmation fonctionnelle.

Un des grands avantages de la programmation fonctionnelle, c'est que le résultat attendu est plus prédictible : avec les mêmes arguments on s'attend à avoir le même résultat à chaque fois.

C'est ce qui explique notamment l'intérêt en principe (en réalité c'est beaucoup plus complexe) de ce type de programmation lorsque l'on a plusieurs programmes s'éxécutant de manière simultanée ou lorsqu'un haut niveau de sûreté est requis.

Le paradigme fonctionnel en Python

Python est un langage multiparadigme, c'est à dire qu'on peut à la fois programmer en utilisant la POO, la programmation impérative et la programmation fonctionnelle.

Ce code ci ne respecte pas le paradigme fonctionnel :

y = 3

def carre(x):
    return x + y

En effet la valeur renvoyée par la fonction va dépendre de la valeur de y qui est extérieure à la fonction.

Ce code respecte le paradigme fonctionnel (dans une certaine mesure) :

def carre(x, y):
    return x + y

D'autres langages

Dans les langages conçus pour être fonctionnel, la récursivité est utilisée. En effet, ces langages forcent l'immutabilité, c'est à dire qu'une "variable" ne peut pas changer de valeur. Or, dans le cas d'une boucle je dois pouvoir incrémenter la variable :

for i in range(10):
    pass

Ici la variable i doit pouvoir changer de valeur.

Ocaml

Ocaml est également un langage multiparadigme, mais c'est avant tout un langage fonctionnel.

let rec fibo n = match n with
  |0 -> 0
  |1 -> 1
  |_ -> fibo(n - 1) + fibo(n - 2);;

Exemple d'arbre binaire en OCaml qui peut prendre n'importe quel type :

type 'a arbre =
| Feuille
| Noeud of 'a * 'a arbre * 'a arbre

le code ci-dessous construit cet arbre: 4 / \ 2 5 / / \ 1 3 6 7

let t =
  Noeud(4,
        Noeud(2,
              Noeud(1, Feuille, Feuille),
              Noeud(3, Feuille, Feuille)
             ),
        Noeud(5,
              Noeud(6, Feuille, Feuille),
              Noeud(7, Feuille, Feuille)
             )
       )

Haskell

Haskell est plus strict que OCaml, c'est un langage qui se veut purement fonctionnel.

fib :: Integer -> Integer
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)