Aller au contenu

19 - Diversité des langages

Un même programme dans dix-huit langages

Il existe des centaines de langages de programmation. Ils ne s’écrivent pas de la même façon, mais la plupart offrent les mêmes constructions élémentaires, c’est-à-dire les briques de base de tout programme : l’affectation, la condition, la boucle et l’appel de fonction.

Un programme est une suite d’instructions. Une instruction est un ordre donné à l’ordinateur : somme = 0 (une affectation), print(somme) (un appel de fonction) ou return somme sont des instructions. Selon les langages, chaque instruction occupe une ligne ou se termine par un signe de ponctuation.

Pour le constater, on écrit le même programme dans dix-huit langages. Ce programme calcule la moyenne des notes d’au moins 10 dans la liste [12, 7, 15, 9, 18, 10], c’est-à-dire la moyenne de 12, 15, 18 et 10 : (12 + 15 + 18 + 10) ÷ 4 = 13,75. Les programmes affichent 13.75, car en programmation la partie décimale d’un nombre est séparée par un point.

Chaque onglet de l’éditeur montre une version du programme. Sous le code, la bande du bas donne la commande à taper dans un terminal pour exécuter le programme, puis ce que le programme affiche. Sous l’éditeur, deux listes comparent le langage choisi avec Python. Le dernier onglet, « Événementiel », montre une page web qui calcule la moyenne quand on clique sur un bouton : on peut y modifier les notes.

moyenne.pyimpératif
 1def moyenne_admis(notes):
 2    somme = 0
 3    nombre = 0
 4    for note in notes:
 5        if note >= 10:
 6            somme = somme + note
 7            nombre = nombre + 1
 8    return somme / nombre
 9
10
11notes = [12, 7, 15, 9, 18, 10]
12print(f"Moyenne des notes d'au moins 10 : {moyenne_admis(notes)}")
$ python3 moyenne.py
Moyenne des notes d'au moins 10 : 13.75

Langage de référence

  • Les autres versions sont comparées à celle-ci.

Particularités du langage Python

  • Un bloc (le corps d’une fonction, d’une boucle ou d’une condition) commence après le caractère : et se repère à son indentation : les lignes décalées vers la droite font partie du bloc.
  • Aucun type n’est écrit : c’est pendant l’exécution que Python constate que somme contient un entier.
  • Chaque instruction occupe une ligne, sans signe de ponctuation à la fin.
  • L’opérateur / donne toujours un nombre à virgule : 55 / 4 vaut 13.75.
  • Python est interprété : l’interpréteur python3 lit les instructions une à une et les exécute aussitôt.

Interpréter ou compiler

Le processeur d’un ordinateur ne comprend pas directement le texte d’un programme : il faut le traduire en instructions du processeur. Il existe deux façons de le faire.

  • Interpréter : un logiciel appelé interpréteur lit les instructions du programme une à une et les exécute aussitôt. C’est ce que fait la commande python3 moyenne.py : python3 est l’interpréteur de Python. JavaScript, PHP et le shell sont aussi interprétés.
  • Compiler : un logiciel appelé compilateur traduit d’abord tout le programme et enregistre le résultat dans un fichier exécutable, que l’on lance ensuite. C’est ce que font gcc pour le C (gcc moyenne.c -o moyenne crée le fichier exécutable moyenne, lancé par ./moyenne), g++ pour le C++ et rustc pour Rust. Go et Swift sont aussi compilés.

Java, Kotlin et Clojure procèdent en deux temps. Leur compilateur (javac pour Java) ne produit pas des instructions pour le processeur de l’ordinateur, mais pour un processeur imaginaire, le même pour tous les ordinateurs : on parle de code intermédiaire. Ce code est ensuite exécuté par la machine virtuelle Java, un logiciel qui joue le rôle de ce processeur imaginaire : il lit le code intermédiaire et le fait exécuter par le vrai processeur. C’est elle que lance la commande java Moyenne. Une fois la machine virtuelle installée, le même fichier compilé fonctionne aussi bien sous Windows que sous macOS ou Linux.

TypeScript est lui aussi compilé, mais en JavaScript, et non en instructions du processeur : son compilateur tsc vérifie les types, puis écrit le fichier moyenne.js, que l’interpréteur node exécute ensuite.

Les styles de programmation

D’un langage à l’autre, le programme ne change pas seulement de mots : il ne suit pas toujours la même démarche. On parle de style de programmation (ou de paradigme).

  • Style impératif : le programme décrit les étapes à suivre, une par une, et des variables changent de valeur pendant l’exécution (somme = somme + note). Les versions en Python, C, C++, JavaScript, TypeScript, Go, Rust, Kotlin, Swift, Lisp et PHP suivent ce style.

  • Style orienté objet (ou style objet) : le programme est organisé en classes, qui regroupent des données et les fonctions qui agissent sur ces données. En Java, tout programme est rangé dans une classe. Ce style est étudié en terminale.

  • Style fonctionnel : le programme est construit en combinant des fonctions, sans aucune variable qui change de valeur. Les versions en Haskell et en Clojure utilisent une fonction qui filtre la liste ; la version en OCaml utilise une fonction récursive, c’est-à-dire une fonction qui s’appelle elle-même. La récursivité est étudiée en terminale.

    En style fonctionnel, le mot variable garde le sens qu’il a en mathématiques : dans f(x) = 2x + 1, la variable x prend une valeur différente à chaque calcul de f, mais ne change pas pendant ce calcul. Le paramètre notes de la version OCaml est une variable de ce type : il désigne une autre liste à chaque appel, mais rien ne peut le modifier pendant le calcul.

  • Style événementiel : le programme associe des fonctions à des événements (un clic, une touche, le chargement d’une page), puis attend ; chaque fonction est appelée quand son événement se produit. C’est le style des interfaces graphiques, déjà rencontré avec tkinter dans le cours sur les interfaces graphiques, et des pages web : le dernier onglet en donne un exemple.

Beaucoup de langages permettent plusieurs styles : on peut aussi écrire des classes en Python, en C++, en Kotlin ou en Swift, et Python possède lui aussi une fonction filter. Lisp, l’un des tout premiers langages, permet le style impératif comme le style fonctionnel, qu’il a contribué à inventer. Clojure, un langage récent de la même famille, encourage le style fonctionnel : la version en Lisp utilise une boucle, celle en Clojure n’en utilise aucune.

Il existe d’autres styles. En programmation logique, par exemple avec le langage Prolog, on décrit des faits et des règles, puis on pose une question : le langage cherche lui-même les réponses qui respectent ces règles.

Le shell est un langage de commandes : un fichier écrit en shell enchaîne les commandes que l’on pourrait taper une à une dans un terminal.

Deux onglets ne montrent pas des langages de programmation :

  • SQL est un langage de requêtes : il sert à interroger une base de données, c’est-à-dire un ensemble de tables enregistrées et gérées par un logiciel spécialisé. SQL est étudié en terminale.
  • HTML est un langage de description : il décrit le contenu d’une page web, que le navigateur affiche, sans rien calculer.

Tableau comparatif

Pour chaque langage, le tableau montre comment s’écrivent l’affectation, la condition et la boucle, comment sont délimités les blocs (le corps d’une boucle, d’une condition ou d’une fonction), et si les types des variables sont écrits dans le code.

Un type non écrit n’est pas pour autant absent : en TypeScript, Go, Rust, Kotlin, Swift, Haskell et OCaml, le compilateur le déduit et le vérifie avant l’exécution, et une variable ne peut jamais changer de type. En Python, en JavaScript, en Lisp, en Clojure et en shell, le type d’une valeur n’est connu qu’au moment de l’exécution. En PHP aussi : même quand les types sont écrits, ils ne sont vérifiés que pendant l’exécution.

LangageAffectationConditionBoucleBlocsTypes écrits
Pythonsomme = 0if note >= 10:for note in notes:indentationnon
Cint somme = 0;if (notes[i] >= 10)for (int i = 0; i < taille; i++){ }oui
C++int somme = 0;if (note >= 10)for (int note : notes){ }oui
JavaScriptlet somme = 0;if (note >= 10)for (const note of notes){ }non
TypeScriptlet somme = 0;if (note >= 10)for (const note of notes){ }pour les paramètres et le résultat
Javaint somme = 0;if (note >= 10)for (int note : notes){ }oui
Gosomme := 0if note >= 10for _, note := range notes{ }pour les paramètres et le résultat
Rustlet mut somme = 0;if note >= 10for &note in notes{ }pour les paramètres et le résultat
Kotlinvar somme = 0if (note >= 10)for (note in notes){ }pour les paramètres et le résultat
Swiftvar somme = 0if note >= 10for note in notes{ }pour les paramètres et le résultat
Haskellaucune variable modifiéefilter (>= 10) notesaucune boucleindentationfacultatifs (écrits ici)
OCamlaucune variable modifiéeif note >= 10 thenaucune boucle (fonction récursive)let ... innon
Lisp(let ((somme 0)) ...)(when (>= note 10) ...)(dolist (note notes) ...)parenthèsesnon
Clojureaucune variable modifiée(filter (fn [note] (>= note 10)) notes)aucune boucleparenthèsesnon
Shellsomme=0if [ "$note" -ge 10 ]for note in "$@"do ... donenon
SQLaucuneWHERE note >= 10aucune boucleaucundans la table
HTMLaucuneaucuneaucune bouclebalisesnon
PHP$somme = 0;if ($note >= 10)foreach ($notes as $note){ }facultatifs (écrits ici)

Domaines d’utilisation, atouts et limites

Aucun langage ne convient à tout : chacun a été conçu pour un usage, et on le choisit selon le besoin (une page web, une application de téléphone, un calcul qui doit être rapide, une base de données). Le tableau indique dans quel domaine chaque langage est le plus utilisé, ce qu’il apporte par rapport aux autres et ses principales limites.

LangageDomaines d’utilisationAtoutsLimites
Pythonenseignement, analyse de données, intelligence artificielle, petits programmes qui automatisent des tâchessyntaxe lisible et courte ; nombreuses bibliothèques pour le calcul, les graphiques et l’intelligence artificielleexécution plus lente que celle d’un programme compilé ; erreurs de type découvertes seulement à l’exécution
Csystèmes d’exploitation (Linux), objets connectés, interpréteurs (celui de Python est écrit en C)programmes très rapides ; compilateurs disponibles pour presque tous les processeursle programmeur gère lui-même la mémoire, ce qui provoque des erreurs et des failles de sécurité
C++jeux vidéo, navigateurs web, logiciels de calculla rapidité du C, avec en plus les classes et une large bibliothèque standardlangage vaste et long à maîtriser ; mêmes risques liés à la mémoire qu’en C
JavaScriptpages web, dans le navigateur ; serveurs, avec Node.jsle langage de programmation des pages web : tous les navigateurs l’exécutent, sans rien installerconversions de types surprenantes : "5" + 1 vaut "51"
TypeScriptapplications web de grande tailleles types, vérifiés avant l’exécution, détectent beaucoup d’erreursune étape de compilation en plus ; les types ne sont plus vérifiés pendant l’exécution
Javalogiciels d’entreprise, serveurs, applications Androidle même fichier compilé fonctionne sur tous les systèmes, grâce à la machine virtuellecode long à écrire : classes obligatoires et types écrits partout
Goserveurs et services en ligne, outils d’hébergement (Docker est écrit en Go)compilation rapide, programmes rapides ; plusieurs tâches menées en même temps facilementlangage volontairement réduit : moins de constructions que Python
Rustlogiciels où la sécurité compte : navigateurs, systèmes d’exploitationaussi rapide que le C, mais le compilateur refuse les programmes qui utilisent mal la mémoireapprentissage difficile : le compilateur refuse beaucoup de programmes
Kotlinapplications Android, recommandé par Google depuis 2019plus court à écrire que Java, et compatible avec les programmes Javadépend de la machine virtuelle et des outils de Java
Swiftapplications pour iPhone, iPad et Macrapide, et plus sûr que les langages qu’Apple utilisait avant luipresque uniquement utilisé sur les appareils Apple
Haskellrecherche, quelques entreprises de la financestyle fonctionnel strict ; types très précis, vérifiés avant l’exécutionpeu répandu dans les entreprises ; demande une autre façon de penser
OCamloutils qui vérifient d’autres programmes, compilateurs, enseignement en classes préparatoirestypes déduits et vérifiés avant l’exécution ; programmes rapidescommunauté réduite, donc moins de bibliothèques
Lispintelligence artificielle des débuts, programmes qui étendent un logiciel (l’éditeur Emacs)un programme Lisp est lui-même une liste, qu’un autre programme peut lire et transformernombreuses parenthèses ; peu utilisé aujourd’hui
Clojureserveurs et services en ligne, traitement de données (la banque Nubank l’utilise pour ses services)style fonctionnel ; des données qui ne se modifient jamais, donc moins d’erreurs quand plusieurs tâches s’exécutent en même temps ; accès à toutes les bibliothèques Javadémarrage lent, dû à la machine virtuelle Java ; messages d’erreur difficiles à lire
Shellautomatisation des tâches d’un ordinateur, administration des serveursenchaîne directement les commandes du terminalmal adapté aux calculs et aux longs programmes ; règles pièges sur les espaces et les guillemets
SQLbases de données des sites web, des banques, des administrationson décrit le résultat voulu, et le logiciel de la base trouve lui-même comment l’obtenirsert seulement à interroger et à modifier des bases de données
HTMLcontenu des pages weblu par tous les navigateursne calcule rien ; l’apparence de la page est décrite à part, en CSS
PHPsites web, côté serveur (Wikipédia et WordPress sont écrits en PHP)conçu pour fabriquer des pages web ; proposé par presque tous les hébergeursdes noms de fonctions peu réguliers, hérités de ses débuts

À retenir

  • Un même programme peut s’écrire dans de nombreux langages ; les constructions élémentaires (affectation, condition, boucle, appel de fonction) se retrouvent dans presque tous les langages de programmation.
  • D’un langage à l’autre, ce qui change, c’est la façon de délimiter les blocs, l’écriture des types, la ponctuation et le style de programmation (impératif, objet, fonctionnel, événementiel, logique).
  • Un programme est soit interprété (Python), soit compilé avant d’être exécuté (C, C++, Rust, Go).
  • Chaque langage est conçu pour un domaine (pages web, applications de téléphone, calcul rapide, bases de données) : on le choisit selon le besoin.
  • Devant un nouveau langage, on cherche d’abord comment il écrit ces constructions élémentaires : on le lit alors beaucoup plus facilement.
  • SQL et HTML ne sont pas des langages de programmation : le premier interroge une base de données, le second décrit une page web.