Aller au contenu

Programmation fonctionnelle

I. Les paradigmes impĂ©ratif et fonctionnel⚓

Objectifs

  • Comprendre la notion de paradigme de programmation
  • Comprendre les notions de paradigme impĂ©ratif et de paradigme fonctionnel
  • Utiliser le paradigme impĂ©ratif et le paradigme fonctionnel en Python

A savoir

  • Un paradigme de programmation est la maniĂšre de formuler le traitement informatique de la rĂ©solution d’un problĂšme.
  • Le paradigme impĂ©ratif consiste Ă  Ă©crire les instructions des codes les unes Ă  la suite des autres dans l’ordre de leur exĂ©cution.
  • Le paradigme impĂ©ratif autorise l’utilisation des fonctions pour Ă©viter de rĂ©pĂ©ter du code.
  • Le paradigme fonctionnel consiste Ă  Ă©crire les codes sous la forme d’un ensemble de fonctions.

II. Les paradigmes de programmation⚓

Lorsque l’on veut Ă©crire un programme informatique pour rĂ©soudre un problĂšme, on choisit une maniĂšre d’écrire le code, une maniĂšre de structurer et d’écrire les instructions : on choisit un paradigme de programmation. Un paradigme de programmation est la maniĂšre de formuler le traitement informatique de la rĂ©solution d’un problĂšme.

Les paradigmes de programmation | Cédric Gerland (20:51)

III. Le paradigme impĂ©ratif⚓

3.1. GĂ©nĂ©ralitĂ©s⚓

Le paradigme de programmation le plus ancien est le paradigme impératif, autrement appelé « programmation impérative ».

Ce paradigme est Ă  l’origine de nombreux langages de programmation tels que les langages C, Pascal ou Basic. Dans un paradigme impĂ©ratif, les instructions sont exĂ©cutĂ©es de maniĂšre sĂ©quentielle, c’est-Ă -dire les unes aprĂšs les autres dans l’ordre dans lequel elles ont Ă©tĂ© Ă©crites. En programmation impĂ©rative, l’ordre d’exĂ©cution du code a de l’importance.

Ce type de programmation est Ă  l’origine de tous les autres types de programmation et se base sur l’utilisation des structures conditionnelles (if), des boucles (while et for) ainsi que des affectations. On distingue deux sous-types de paradigmes impĂ©ratifs : le paradigme sĂ©quentiel et le paradigme procĂ©dural. Leur diffĂ©rence tient dans le fait que la programmation procĂ©durale autorise l’usage de fonctions pour rĂ©utiliser du code, alors que la programmation sĂ©quentielle ne l’autorise pas.

On apprend gĂ©nĂ©ralement la programmation en commençant par le paradigme impĂ©ratif. En pratique, lorsque l’on parle de paradigme impĂ©ratif, il s’agit en rĂ©alitĂ© du paradigme procĂ©dural, car l’usage des fonctions est recommandĂ© pour Ă©viter de rĂ©pĂ©ter du code.

3.2. Exemple avec Python⚓

Le paradigme impératif est supporté par la plupart des langages de programmation.

Le langage Python est un langage multi-paradigme, qui autorise naturellement la programmation impérative.

Exemple de code en programmation impérative
🐍 Editeur
"""
Code permettant de calculer la moyenne du tableau tab = [1, 2, 3, 4, 5]
"""
tab = [1, 2, 3, 4, 5]     # On définit le tableau.
somme = 0                 # On initialise la somme des éléments de tab à 0.
for elt in tab:           # On parcourt le tableau tab et on affecte à elt les éléments de tab.}
    somme = somme + elt   # On ajoute elt à la somme précédente.
moyenne = somme/len(tab)  # On affecte Ă  la variable moyenne le quotient de la variable somme et de la taille du tableau tab.
print(moyenne)            # On affiche la moyenne.

On utilise ici le paradigme séquentiel car les instructions sont exécutées ligne par ligne.

En programmation procédurale, cela peut donner le code suivant :

Exemple de code en programmation procédurale
🐍 Editeur
"""
Autre code permettant de calculer la moyenne du tableau tab = [1, 2, 3, 4, 5]
"""
tab = [1, 2, 3, 4, 5]             # On définit le tableau.

def somme(tab):                   # On définit la fonction somme qui prend en paramÚtre tab un tableau de nombres et retourne la somme de ses éléments.
    resultat = 0
    for elt in tab:
        resultat = resultat + elt
    return resultat

def moyenne(tab):                 # On définit la fonction moyenne qui prend en paramÚtre tab un tableau de nombres et retourne la moyenne de ses éléments.
    n = len(tab)
    return somme(tab)/n

print(moyenne(tab))               # On affiche la moyenne.

Ce code peut paraßtre plus long que le précédent, mais les fonctions somme(tab) et moyenne(tab) seront directement réutilisables sans nécessité de les coder à nouveau car elle ont été définies.

3.3. Avantages et inconvĂ©nients⚓

L’avantage principal de la programmation impĂ©rative est que le code est trĂšs lisible, ce qui en facilite l’apprentissage.

Ce paradigme produit toutefois vite des programmes volumineux, les codes peuvent ainsi perdre en clarté. De plus, en cas de modification ou de mise à jour du code, la programmation impérative peut induire un bon nombre de bugs puisque il faut relire le code dans son entier et effectuer de nombreuses retouches.

IV. Le paradigme fonctionnel⚓

4.1. GĂ©nĂ©ralitĂ©s⚓

Le paradigme fonctionnel consiste à décomposer les programmes réalisés en un ensemble de fonctions.

En programmation fonctionnelle l’ordre d’exĂ©cution du code n’a aucune importance.

La programmation fonctionnelle consiste Ă  Ă©crire le rĂ©sultat que devra rendre la fonction selon les donnĂ©es fournies. Ce rĂ©sultat est dĂ©crit par une expression dĂ©pendant des paramĂštres de la fonction et est notĂ© en Python aprĂšs le mot-clĂ© return. Il n’est plus utile ici de dĂ©crire une suite d’instructions, comme en programmation impĂ©rative. Seul le rĂ©sultat compte. Si l’écriture de l’expression rĂ©sultat est trop complexe, il est possible de dĂ©composer le problĂšme et de prĂ©senter l’écriture du rĂ©sultat comme la composition de plusieurs fonctions intermĂ©diaires. Il est aussi possible de dĂ©composer par cas grĂące Ă  l’expression conditionnelle.

Fonctions pures et impures

Les fonctions doivent idĂ©alement produire des sorties qui ne dĂ©pendent strictement que de leurs arguments, sans que ces sorties ne dĂ©pendent de variables externes Ă  la fonction elle-mĂȘme. On parle alors de « fonctions pures ».

A contrario, les fonctions qui ne respectent pas ce principe sont appelées des « fonctions impures ».

Exemple de fonction impure
🐍 Editeur
n = 5          # On affecte 5 Ă  la variable n.

def fonc1(x):  # On définit la fonction fonc1(x).
    global n   # Dans la fonction, on dĂ©clare la variable n comme globale, elle est la mĂȘme que celle de la premiĂšre ligne.
    n = n + x  # On affecte n + x Ă  la variable n.
    return n   # On retourne n.

Cette fonction est impure car n est une variable externe Ă  la fonction fonc1(a).

En testant fonc1(2) deux fois de suite, on n’obtient d’ailleurs pas le mĂȘme rĂ©sultat.

Exemple de fonction pure
🐍 Editeur
def fonc2(x):     # On définit la fonction fonc2(x).
    return x + 5  # On retourne x + 5.

Si on teste fonc2(2) deux fois de suite, on obtiendra bien alors le mĂȘme rĂ©sultat.

4.2. Avec Python⚓

Le paradigme impĂ©ratif n’est pas supportĂ© par tous les langages de programmation.

Le langage Python offre un certain nombre d’outils pour utiliser le paradigme fonctionnel.

  • Les lambda fonctions ou fonctions anonymes Elles permettent de dĂ©finir des fonctions sans le mot-clĂ© def et pour lesquelles le mot-clĂ© return est implicite. Ces fonctions utilisent le mot-clĂ© lambda.

    Exemple de lambda fonction
    🐍 Editeur
    """
    Deux façons d’écrire la fonction carre qui prend en paramĂštre un nombre a et retourne son carrĂ©.
    """
    carre(a):               # Fonction classique
        return a*a
    
    carre = lambda a : a*a  # Lambda fonction
    

    Dans les deux cas, l’utilisation de la fonction est la mĂȘme. Par exemple, carre(3) retournera 9.

    Dans cet exemple, la lambda fonction est référencée par la variable carre.

    Il est possible de ne pas utiliser de variable qui référence une lambda fonction, notamment avec les fonctions map, filter et reduce.

  • La fonction map

    La fonction map permet d’appliquer une fonction Ă  tous les Ă©lĂ©ments d’un tableau.

    map(fonc, tab) prend ainsi en paramÚtres une fonction fonc et un tableau tab (ou un objet itérable) ; cette fonction retourne un itérateur dont les éléments sont les images des éléments de tab par la fonction fonc.

    La fonction list() permet d’en obtenir une liste.

    Exemple d'utilisation de la fonction map
    🐍 Editeur
    """
    On veut créer le tableau des carrés du tableau tab = [1, 2, 3, 4, 5].
    """
    list(map(lambda x : x*x, tab))
    
  • La fonction filter

    La fonction filter permet de filtrer les Ă©lĂ©ments d’un tableau.

    filter(fonc, tab) prend ainsi en paramÚtres une fonction fonc qui retourne True ou False et un tableau tab (ou un objet itérable) ; cette fonction retourne un itérateur dont les éléments de tab ont True pour image par la fonction fonc.

    Exemple d'utilisation de la fonction filter
    🐍 Editeur
    """
    On veut créer le tableau des nombres pairs de tab = [1, 2, 3, 4, 5].
    """
    list(filter(lambda x : x%2 == 0, tab))
    
  • La fonction reduce

    La fonction reduce permet de calculer une valeur Ă  partir d’une fonction et de tous les Ă©lĂ©ments d’un tableau.

    reduce(fonc, tab), du module functools, prend ainsi en paramÚtres une fonction fonc à deux paramÚtres et un tableau tab (ou un objet itérable) ; cette fonction retourne une valeur.

    Principe

    Au premier appel, les deux premiers éléments de tab sont les arguments de fonc.

    Le résultat et le troisiÚme élément de tab sont ensuite les arguments de fonc, et ainsi de suite.

    Ainsi, aprÚs le parcours de tous les éléments de tab, la valeur finale est retournée.

    Exemple d'utilisation de la fonction reduce
    🐍 Editeur
    """
    On veut calculer la somme des éléments de tab = [1, 2, 3, 4, 5].
    """
    reduce(lambda a, b : a+b, tab)
    

4.3. Avantages et inconvĂ©nients⚓

L’avantage principal du paradigme fonctionnel est de produire des codes courts et faciles Ă  dĂ©bugger. Il suffit de tester chacune de ses fonctions pour valider les codes.

La programmation fonctionnelle n’est toutefois pas facile Ă  apprĂ©hender, elle demande une certaine expertise. Elle ne convient de plus pas Ă  toutes les tĂąches.

Le paradigme fonctionnel (doc. Eduscol)⚓

Fichier PDF

Block2py : programmation impĂ©rative ou fonctionelle par blocs⚓

Application Block2py (en ligne)