Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Licence CC BY-NC-ND Thierry Parmentelat & Arnaud Legout Inria - UCA

Complément - niveau intermédiaire

Parmi les langages typés, on distingue les langages à typage statique et ceux à typage dynamique. Ce notebook tente d’éclaircir ces notions pour ceux qui n’y sont pas familiers.

Typage statique

À une extrémité du spectre, on trouve les langages compilés, dits à typage statique, comme par exemple C ou C++.

En C on écrira, par exemple, une version simpliste de la fonction factoriel comme ceci :

int factoriel(int n) {
    int result = 1;
    for (int loop = 1; loop <= n; loop++)
        result *= loop;
    return result;
}

Comme vous pouvez le voir - ou le deviner - toutes les variables utilisées ici (comme par exemple n, result et loop) sont typées :

Ces informations de type ont essentiellement trois fonctions :

#include <stdio.h>

int main(int argc, char *argv[]) {
    /* le premier argument de la ligne de commande est argv[1] */
    char *input = argv[1];
    /* calculer son factoriel et afficher le résultat */
    printf("Factoriel (%s) = %d\n", input, factoriel(input));
    /*                                               ^^^^^

     * ici on appelle factoriel avec une entrée de type 'chaîne de caractères' */
}

alors le compilateur va remarquer qu’on essaie d’appeler factoriel avec comme argument input qui, pour faire simple, est une chaîne de caractères et comme factoriel s’attend à recevoir un entier, ce programme n’a aucune chance de compiler.

On parle alors de typage statique, en ce sens que chaque variable a exactement un type qui est défini par le programmeur une bonne fois pour toutes.

C’est ce qu’on appelle le contrôle de type, ou type-checking en anglais. Si on ignore le point sur le contrôle fin de la mémoire, qui n’est pas crucial à notre sujet, ce modèle de contrôle de type présente :

Cela étant dit, le typage statique en C n’empêche pas le programmeur débutant d’essayer d’écrire dans la mémoire à partir d’un pointeur NULL - et le programme de s’interrompre brutalement. Il faut être conscient des limites du typage statique.

Typage dynamique

À l’autre bout du spectre, on trouve des langages comme, eh bien, Python.

Pour comprendre cette notion de typage dynamique, regardons la fonction suivante somme.

def somme(*largs):
    "retourne la somme de tous ses arguments"
    if not largs:
        return 0
    result = largs[0]
    for i in range(1, len(largs)):
        result += largs[i]
    return result

Naturellement, vous n’êtes pas à ce stade en mesure de comprendre le fonctionnement intime de la fonction. Mais vous pouvez tout de même l’utiliser :

somme(12, 14, 300)
326
liste1 = ['a', 'b', 'c']
liste2 = [0, 20, 30]
liste3 = ['spam', 'eggs']
somme(liste1, liste2, liste3)
['a', 'b', 'c', 0, 20, 30, 'spam', 'eggs']

Vous pouvez donc constater que somme peut fonctionner avec des objets de types différents: on peut lui passer des nombres, ou lui passer des listes. En fait, telle qu’elle est écrite, elle va fonctionner s’il est possible de faire + entre ses arguments. Ainsi, par exemple, on pourrait même faire :

# Python sait faire + entre deux chaînes de caractères
somme('abc', 'def')
'abcdef'

Mais par contre on ne pourrait pas faire

# ceci va déclencher une exception à l'exécution
somme(12, [1, 2, 3])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[5], line 2
      1 # ceci va déclencher une exception à l'exécution
----> 2 somme(12, [1, 2, 3])

Cell In[1], line 7, in somme(*largs)
      5 result = largs[0]
      6 for i in range(1, len(largs)):
----> 7     result += largs[i]
      8 return result

TypeError: unsupported operand type(s) for +=: 'int' and 'list'

Il est utile de remarquer que le typage de Python, qui existe bel et bien comme on le verra, est qualifié de dynamique parce que le type est attaché à un objet et non à la variable qui le référence. On aura bien entendu l’occasion d’approfondir tout ça dans le cours.

En Python, on fait souvent référence au typage sous l’appellation duck typing, de manière imagée :

If it looks like a duck and quacks like a duck, it’s a duck.

On voit qu’on se trouve dans une situation très différente de celle du programmeur C/C++, en ce sens que :

Il y a deux points de vue vis-à-vis de la question du typage.

Les gens habitués au typage statique se plaignent du typage dynamique en disant qu’on peut écrire des programmes faux et qu’on s’en rend compte trop tard - à l’exécution.

À l’inverse les gens habitués au typage dynamique font valoir que le typage statique est très partiel, par exemple, en C si on essaie d’écrire dans un pointeur NULL, le système d’exploitation ne le permet pas et le programme sort tout aussi brutalement.

Bref, selon le point de vue, le typage dynamique est vécu comme un inconvénient (pas assez de bonnes propriétés détectées par le langage) ou comme un avantage (pas besoin de passer du temps à déclarer le type des variables, ni à faire des conversions pour satisfaire le compilateur).

Vous remarquerez cependant à l’usage, qu’en matière de vitesse de développement, les inconvénients du typage dynamique sont très largement compensés par ses avantages.

Type hints

Signalons enfin que depuis python-3.5, il est possible d’ajouter des annotations de type, pour expliciter les suppositions qui sont faites par le programmeur pour le bon fonctionnement du code.

Nous aurons là encore l’occasion de détailler ce point dans le cours, signalons simplement que ces annotations sont totalement optionnelles, et que même lorsqu’elles sont présentes elles ne sont pas utilisées à l’exécution par l’interpréteur. L’idée est plutôt de permettre à des outils externes, comme par exemple mypy, d’effectuer des contrôles plus poussés concernant la correction du programme.