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.
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)}")
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
sommecontient un entier. - Chaque instruction occupe une ligne, sans signe de ponctuation à la fin.
- L’opérateur
/donne toujours un nombre à virgule :55 / 4vaut13.75. - Python est interprété : l’interpréteur
python3lit les instructions une à une et les exécute aussitôt.
1#include <stdio.h>
2
3double moyenne_admis(int notes[], int taille) {
4 int somme = 0;
5 int nombre = 0;
6 for (int i = 0; i < taille; i++) {
7 if (notes[i] >= 10) {
8 somme = somme + notes[i];
9 nombre = nombre + 1;
10 }
11 }
12 return (double) somme / nombre;
13}
14
15int main(void) {
16 int notes[] = {12, 7, 15, 9, 18, 10};
17 printf("Moyenne des notes d'au moins 10 : %.2f\n", moyenne_admis(notes, 6));
18 return 0;
19}
Points communs avec Python
- La même démarche : une fonction, une boucle qui parcourt les notes, une condition et deux variables qui comptent.
- Le même opérateur de comparaison
>=et la même affectationsomme = somme + ....
Particularités du langage C
- La première ligne,
#include <stdio.h>, est remplacée avant la compilation par le contenu du fichierstdio.h(pour standard input/output, « entrées et sorties standard »). Ce fichier, fourni avec le C, déclare les fonctions d’affichage et de lecture, dontprintf: sans cette ligne, le compilateur refuse d’utiliserprintf. C’est l’équivalent d’unimporten Python. - Chaque variable est déclarée, c’est-à-dire annoncée avec son type, avant d’être utilisée :
intpour un entier,doublepour un nombre à virgule. Une variable déclaréeintne peut contenir qu’un entier. doublesignifie « double précision » : en pratique, undoubleoccupe 64 bits, deux fois plus qu’unfloat, le type à virgule en simple précision (32 bits). Le cours « 05 - Réels » présente ce format de la norme IEEE 754, qui est aussi celui dufloatde Python. Le mot est plus ancien que cette norme : il vient du langage Fortran, qui avait déjà un typeDOUBLE PRECISIONdans les années 1960.- Les blocs sont délimités par des accolades
{ }, et chaque instruction (affectation, appel de fonction,return) se termine par un point-virgule. - Les notes sont rangées dans un tableau (
int notes[]), l’équivalent d’une liste Python dont le nombre d’éléments ne peut pas changer. - Une fonction qui reçoit un tableau ne peut pas connaître son nombre d’éléments : il n’existe pas d’équivalent de
len. On lui transmet donc ce nombre,6, dans un second paramètre,taille. - La boucle
for (int i = 0; i < taille; i++)fait prendre àiles valeurs 0, 1, …,taille - 1, commefor i in range(taille)en Python ;notes[i]est la note placée à la positioni. (double) sommetransforme l’entiersommeen nombre à virgule avant la division : en C, la division de deux entiers donne un entier (55 / 4vaudrait13).- C est compilé : le compilateur
gcctraduit tout le programme en instructions du processeur et crée le fichier exécutablemoyenne, que l’on lance avec./moyenne. L’exécution commence toujours par la fonctionmain. - Dans
int main(void),intest le type de ce que renvoiemain, etvoidsignifie qu’elle ne reçoit aucun argument.return 0;renvoie au système d’exploitation le code de retour 0, qui signifie « tout s’est bien passé » ; un autre nombre signale une erreur. C’est ce code que lit le&&de la commandegcc moyenne.c -o moyenne && ./moyenne:./moyennen’est lancé que sigcca renvoyé 0, c’est-à-dire si la compilation a réussi. Depuis 1999, la norme du C permet d’omettrereturn 0;à la fin demain: le programme renvoie alors 0. Python, lui, renvoie 0 tout seul à la fin du programme.
1#include <iostream>
2#include <vector>
3
4double moyenne_admis(const std::vector<int>& notes) {
5 int somme = 0;
6 int nombre = 0;
7 for (int note : notes) {
8 if (note >= 10) {
9 somme = somme + note;
10 nombre = nombre + 1;
11 }
12 }
13 return static_cast<double>(somme) / nombre;
14}
15
16int main() {
17 std::vector<int> notes = {12, 7, 15, 9, 18, 10};
18 std::cout << "Moyenne des notes d'au moins 10 : " << moyenne_admis(notes) << std::endl;
19 return 0;
20}
Points communs avec Python
- La même démarche : une fonction, une boucle sur les notes, une condition et deux variables qui comptent.
for (int note : notes)se lit « pour chaque note denotes», commefor note in notes.
Particularités du langage C++
- C++, créé au début des années 1980, est une extension du C : presque tout programme écrit en C est aussi un programme C++. Il y ajoute notamment les classes, c’est-à-dire le style orienté objet, et une bibliothèque beaucoup plus riche.
- Comme en C, les types sont déclarés (
int,double), les blocs sont délimités par des accolades, chaque instruction se termine par un point-virgule, et l’exécution commence par la fonctionmain. - Comme en C,
return 0;à la fin demainrenvoie au système d’exploitation le code de retour 0, qui signifie « tout s’est bien passé ». En C++, cette ligne peut être omise dansmain: le programme renvoie alors 0. std::vector<int>est une liste d’entiers qui connaît son nombre d’éléments et peut grandir, contrairement au tableau du C : il n’est donc plus nécessaire de transmettre le nombre de notes à la fonction.- Dans
const std::vector<int>& notes, le signe&indique que la fonction utilise la liste sans la recopier, etconstqu’elle ne la modifiera pas. std::indique quevectoretcoutviennent de la bibliothèque standard du C++ ; les lignes#include <iostream>et#include <vector>chargent les parties de cette bibliothèque dont le programme a besoin, comme#include <stdio.h>en C.std::cout << ...affiche : chaque signe<<envoie un morceau (le texte, puis la moyenne) vers l’écran, etstd::endlpasse à la ligne.static_cast<double>(somme)transforme l’entier en nombre à virgule avant la division ; c’est l’écriture C++ de(double) somme.- C++ est compilé : le compilateur
g++crée le fichier exécutablemoyenne. C’est le langage de nombreux logiciels où la rapidité compte : jeux vidéo, navigateurs web, logiciels de calcul.
1function moyenneAdmis(notes) {
2 let somme = 0;
3 let nombre = 0;
4 for (const note of notes) {
5 if (note >= 10) {
6 somme = somme + note;
7 nombre = nombre + 1;
8 }
9 }
10 return somme / nombre;
11}
12
13const notes = [12, 7, 15, 9, 18, 10];
14console.log(`Moyenne des notes d'au moins 10 : ${moyenneAdmis(notes)}`);
Points communs avec Python
- Aucun type n’est écrit, comme en Python.
for (const note of notes)parcourt directement les notes, commefor note in notes.- Dans un texte placé entre deux accents graves,
${...}insère une valeur, comme{...}dans une f-string.
Particularités du langage JavaScript
letcrée une variable dont la valeur peut changer ;const(pour « constante ») crée une variable dont la valeur ne change plus.functionintroduit une fonction, commedefen Python.- Les blocs sont délimités par des accolades et les instructions se terminent par un point-virgule, comme en C.
console.logaffiche un texte, commeprint.- C’est le langage des pages web, étudié dans le chapitre sur le Web : il s’exécute dans le navigateur. Ici, il est exécuté par Node.js, un interpréteur qui fait fonctionner JavaScript en dehors d’un navigateur.
1function moyenneAdmis(notes: number[]): number {
2 let somme = 0;
3 let nombre = 0;
4 for (const note of notes) {
5 if (note >= 10) {
6 somme = somme + note;
7 nombre = nombre + 1;
8 }
9 }
10 return somme / nombre;
11}
12
13const notes: number[] = [12, 7, 15, 9, 18, 10];
14console.log(`Moyenne des notes d'au moins 10 : ${moyenneAdmis(notes)}`);
Points communs avec Python
for (const note of notes)parcourt directement les notes, commefor note in notes.- Dans un texte placé entre deux accents graves,
${...}insère une valeur, comme{...}dans une f-string. - Le type des variables
sommeetnombren’est pas écrit : le compilateur le déduit de la valeur0.
Particularités du langage TypeScript
- TypeScript, c’est JavaScript auquel on ajoute l’écriture des types : en supprimant
: number[]et: number, on retrouve exactement la version JavaScript. notes: number[]indique que le paramètre est un tableau de nombres, et): numberque la fonction renvoie un nombre.- Le compilateur
tscvérifie les types avant l’exécution : l’appelmoyenneAdmis("12 7 15")est refusé, car un texte n’est pas un tableau de nombres. Il traduit ensuite le programme en JavaScript :tsc moyenne.tscrée le fichiermoyenne.js, quenodeexécute. - Le compilateur s’installe avec la commande
npm install -g typescript.
1public class Moyenne {
2
3 static double moyenneAdmis(int[] notes) {
4 int somme = 0;
5 int nombre = 0;
6 for (int note : notes) {
7 if (note >= 10) {
8 somme = somme + note;
9 nombre = nombre + 1;
10 }
11 }
12 return (double) somme / nombre;
13 }
14
15 public static void main(String[] args) {
16 int[] notes = {12, 7, 15, 9, 18, 10};
17 System.out.println("Moyenne des notes d'au moins 10 : " + moyenneAdmis(notes));
18 }
19}
Points communs avec Python
- La même boucle sur les notes :
for (int note : notes)se lit « pour chaque note denotes». - La même condition
note >= 10.
Particularités du langage Java
- Tout le code est rangé dans une classe,
Moyenne: en Java, aucune fonction ne peut exister en dehors d’une classe. C’est la marque du style orienté objet, présenté plus bas. - Comme en C, chaque variable est déclarée avec son type :
int,double, ouint[]pour un tableau d’entiers. Le type de la valeur renvoyée est écrit devant le nom de la fonction :double moyenneAdmis. - Une fonction rangée dans une classe s’appelle une méthode. L’exécution commence par la méthode
main, écritepublic static void main.voidsignifie que la méthode ne renvoie rien.publicsignifie qu’elle peut être utilisée depuis l’extérieur de la classe : c’est ce qui permet à la machine virtuelle Java de la lancer. staticsignifie que la méthode appartient à la classe elle-même et peut être appelée directement. Sans ce mot, il faudrait d’abord fabriquer un objet à partir de la classe, ce que l’on apprend en terminale. C’est pourquoimoyenneAdmis, appelée parmain, est elle aussi déclaréestatic.- Les blocs sont délimités par des accolades et les instructions se terminent par un point-virgule, comme en C.
System.out.printlnaffiche un texte. Le signe+met bout à bout le texte et la moyenne : Java transforme automatiquement le nombre13.75en texte. En Python,"Moyenne : " + 13.75provoque une erreur (TypeError) ; il faut écrirestr(13.75)ou utiliser une f-string.- Le programme est compilé par
javac, puis exécuté par la machine virtuelle Java avec la commandejava Moyenne(voir la section « Interpréter ou compiler », sous l’éditeur).
1package main
2
3import "fmt"
4
5func moyenneAdmis(notes []int) float64 {
6 somme := 0
7 nombre := 0
8 for _, note := range notes {
9 if note >= 10 {
10 somme = somme + note
11 nombre = nombre + 1
12 }
13 }
14 return float64(somme) / float64(nombre)
15}
16
17func main() {
18 notes := []int{12, 7, 15, 9, 18, 10}
19 fmt.Println("Moyenne des notes d'au moins 10 :", moyenneAdmis(notes))
20}
Points communs avec Python
- Pas de parenthèses autour de la condition :
if note >= 10. - Pas de point-virgule à la fin des instructions.
Particularités du langage Go
:=crée une variable et lui donne sa première valeur ; Go en déduit le type, ici un entier.- Ce type est ensuite fixé : écrire
somme = 2.5serait refusé à la compilation, carsommeest un entier. En Go, une variable a toujours un type, même quand on ne l’écrit pas. - Les types s’écrivent après le nom :
notes []intest une liste d’entiers. Le type de la valeur renvoyée suit les parenthèses :float64, un nombre à virgule. funcintroduit une fonction, commedefen Python.- À chaque tour,
range notesfournit la position et la note ; le tiret bas_indique que la position n’est pas utilisée. - Les accolades sont obligatoires autour des blocs.
- Avant de diviser, il faut transformer les entiers en nombres à virgule avec
float64(...). import "fmt"charge la bibliothèquefmt, qui fournit la fonction d’affichagefmt.Println. Go est compilé :go runcompile le programme puis l’exécute aussitôt.
1fn moyenne_admis(notes: &[i32]) -> f64 {
2 let mut somme = 0;
3 let mut nombre = 0;
4 for ¬e in notes {
5 if note >= 10 {
6 somme = somme + note;
7 nombre = nombre + 1;
8 }
9 }
10 somme as f64 / nombre as f64
11}
12
13fn main() {
14 let notes = [12, 7, 15, 9, 18, 10];
15 println!("Moyenne des notes d'au moins 10 : {}", moyenne_admis(¬es));
16}
Points communs avec Python
for ... inparcourt les notes, comme en Python.- Pas de parenthèses autour de la condition.
Particularités du langage Rust
- Une variable ne peut pas changer de valeur, sauf si on l’annonce avec le mot
mut(pour « modifiable ») :let mut somme = 0. fnintroduit une fonction, commedefen Python. Les types s’écrivent après le nom :i32désigne un entier etf64un nombre à virgule ; le type de la valeur renvoyée suit la flèche->.- Le signe
&, dans le type&[i32]et dans l’appelmoyenne_admis(¬es), indique que la fonction consulte le tableau des notes sans en faire une copie. - La dernière ligne de la fonction, écrite sans point-virgule, est la valeur renvoyée : pas besoin de
return. as f64transforme un entier en nombre à virgule avant la division.println!affiche un texte ; les accolades{}marquent l’endroit où la moyenne s’insère.- Rust est compilé :
rustccrée le fichier exécutablemoyenne, que l’on lance avec./moyenne.
1fun moyenneAdmis(notes: List<Int>): Double {
2 var somme = 0
3 var nombre = 0
4 for (note in notes) {
5 if (note >= 10) {
6 somme = somme + note
7 nombre = nombre + 1
8 }
9 }
10 return somme.toDouble() / nombre
11}
12
13fun main() {
14 val notes = listOf(12, 7, 15, 9, 18, 10)
15 println("Moyenne des notes d'au moins 10 : ${moyenneAdmis(notes)}")
16}
Points communs avec Python
for (note in notes)se lit commefor note in notes.- Dans le texte à afficher,
${...}insère la valeur de la moyenne, comme{...}dans une f-string.
Particularités du langage Kotlin
varcrée une variable dont la valeur peut changer ;valcrée une variable en lecture seule, dont la valeur ne change plus. Ce sont les mots de la documentation de Kotlin.funintroduit une fonction, commedefen Python.- Les types s’écrivent après le nom, séparés par deux-points :
notes: List<Int>est une liste d’entiers. Le type de la valeur renvoyée suit les parenthèses :: Double, un nombre à virgule. - Les blocs sont délimités par des accolades, sans point-virgule.
toDouble()transforme l’entier en nombre à virgule avant la division.- Kotlin est le langage des applications Android. Comme Java, il est compilé (
kotlinc), puis exécuté par la machine virtuelle Java.
1func moyenneAdmis(_ notes: [Int]) -> Double {
2 var somme = 0
3 var nombre = 0
4 for note in notes {
5 if note >= 10 {
6 somme = somme + note
7 nombre = nombre + 1
8 }
9 }
10 return Double(somme) / Double(nombre)
11}
12
13let notes = [12, 7, 15, 9, 18, 10]
14print("Moyenne des notes d'au moins 10 : \(moyenneAdmis(notes))")
Points communs avec Python
for note in notesetif note >= 10, sans parenthèses, comme en Python.- Pas de point-virgule à la fin des instructions.
Particularités du langage Swift
varcrée une variable, dont la valeur peut changer ;letcrée une constante, dont la valeur ne change plus. Ce sont les mots de la documentation de Swift.funcintroduit une fonction ; le type de la valeur renvoyée est annoncé par une flèche :-> Double, un nombre à virgule.- Le paramètre s’écrit
_ notes: [Int], une liste d’entiers. Par défaut, Swift oblige à écrire le nom du paramètre à chaque appel :moyenneAdmis(notes: notes). Le tiret bas_supprime cette obligation, et l’on écrit simplementmoyenneAdmis(notes). Python accepte aussi l’écrituremoyenne_admis(notes=notes), mais sans l’imposer. Double(somme)transforme l’entier en nombre à virgule avant la division.- Dans un texte,
\(...)insère une valeur, comme{...}dans une f-string. - Swift est le langage des applications Apple (iPhone, Mac).
1moyenneAdmis :: [Int] -> Double
2moyenneAdmis notes = fromIntegral (sum admis) / fromIntegral (length admis)
3 where
4 admis = filter (>= 10) notes
5
6main :: IO ()
7main = do
8 let notes = [12, 7, 15, 9, 18, 10]
9 putStrLn ("Moyenne des notes d'au moins 10 : " ++ show (moyenneAdmis notes))
Points communs avec Python
- Une fonction,
moyenneAdmis, reçoit la liste des notes et renvoie la moyenne ;mainaffiche le résultat. sumetlengthjouent le même rôle quesumetlenen Python.
Particularités du langage Haskell
- Il n’y a aucune boucle et aucune variable dont la valeur change : au lieu de décrire les étapes du calcul, on décrit le résultat. C’est le style fonctionnel, présenté plus bas. En Python, la version la plus proche serait
admis = [note for note in notes if note >= 10], suivie dereturn sum(admis) / len(admis). - Ligne 1 :
moyenneAdmis :: [Int] -> Doubleannonce le type de la fonction.::se lit « a pour type » ;[Int]est une liste d’entiers ; la flèche->sépare ce que la fonction reçoit (à gauche) de ce qu’elle renvoie (à droite), ici un nombre à virgule,Double. (>= 10)est une comparaison à laquelle il manque le nombre de gauche : c’est donc une fonction, qui reçoit une note et répondTruesi elle est supérieure ou égale à 10,Falsesinon.filter (>= 10) notesapplique ce test à chaque note et construit la liste des notes pour lesquelles il répondTrue:[12, 15, 18, 10].- On appelle une fonction sans parenthèses ni virgules : on écrit son nom, puis ses arguments séparés par des espaces.
moyenneAdmis notescorrespond àmoyenne_admis(notes)en Python, et dansfilter (>= 10) notes, la fonctionfilterreçoit deux arguments. Les parenthèses servent seulement à regrouper :fromIntegral (sum admis)appliquefromIntegralau résultat desum admis. - La division
/n’accepte pas les entiers :fromIntegraltransforme donc la somme (55) et le nombre de notes (4) en nombres à virgule avant de diviser. Pour une division entière, Haskell utilise une autre fonction,div. wheredonne un nom,admis, à une valeur utilisée dans le calcul. Ce nom est défini après la formule qui l’utilise : en Haskell, l’ordre des définitions n’a pas d’importance.- Les lignes qui commencent par
mainforment le programme proprement dit.main :: IO ()annonce une action, c’est-à-dire un calcul qui communique avec l’extérieur, ici pour afficher.doenchaîne plusieurs étapes,letdonne un nom à la liste des notes, etputStrLnaffiche une ligne de texte. - Dans le texte affiché,
++met deux textes bout à bout etshowtransforme la moyenne en texte, commestr()en Python. - Une fonction comme
moyenneAdmisne fait que calculer : elle ne peut ni afficher, ni modifier quoi que ce soit, et elle donne toujours le même résultat pour les mêmes arguments. Tout ce qui touche à l’extérieur est réservé aux actions commemain. runghcexécute directement le programme ; le compilateurghcpermet aussi d’en faire un fichier exécutable.
1let rec somme_et_nombre notes =
2 match notes with
3 | [] -> (0, 0)
4 | note :: reste ->
5 let (somme, nombre) = somme_et_nombre reste in
6 if note >= 10 then (somme + note, nombre + 1) else (somme, nombre)
7
8let moyenne_admis notes =
9 let (somme, nombre) = somme_et_nombre notes in
10 float_of_int somme /. float_of_int nombre
11
12let () =
13 let notes = [12; 7; 15; 9; 18; 10] in
14 Printf.printf "Moyenne des notes d'au moins 10 : %g\n" (moyenne_admis notes)
Points communs avec Python
- Une fonction,
moyenne_admis, reçoit la liste des notes et renvoie la moyenne ; les noms s’écrivent avec des tirets bas, comme en Python. - Aucun type n’est écrit : OCaml les déduit seul. Il les vérifie toutefois avant l’exécution, et une valeur ne peut jamais changer de type.
if ... then ... else ...choisit entre deux possibilités, commeifetelseen Python.
Particularités du langage OCaml
letlie un nom à une valeur (let notes = ...) ou à une fonction (let moyenne_admis notes = ...) : on parle de liaison. Une liaison ne se modifie pas : écrire une seconde foislet notes = ...crée une nouvelle liaison, qui masque l’ancienne sans la changer. Il n’existe donc aucune affectation commesomme = somme + note.let ... indonne un nom utilisable seulement dans le calcul écrit aprèsin:let (somme, nombre) = ... inest suivi du calcul qui se sert desommeet denombre.- La boucle est remplacée par une fonction récursive (mot
rec), c’est-à-dire une fonction qui s’appelle elle-même. Pour la liste[12; 7; 15],somme_et_nombredemande d’abord le résultat pour[7; 15], qui demande celui de[15], qui demande celui de la liste vide[], qui vaut(0, 0). Les résultats remontent ensuite :[15]donne(15, 1),[7; 15]donne encore(15, 1)car 7 est écarté, et[12; 7; 15]donne(27, 2). match notes withdistingue deux cas, chacun introduit par une barre|:[], la liste vide, etnote :: reste, une liste formée d’une première note suivie des autres. Ce second cas donne en même temps un nom à la première note (note) et aux autres (reste).- La fonction renvoie deux valeurs à la fois, sous forme de couple
(somme, nombre), comme un tuple en Python.let (somme, nombre) = ...récupère les deux valeurs d’un coup, commesomme, nombre = ...en Python. if ... then ... else ...donne toujours une valeur :(somme + note, nombre + 1)ou(somme, nombre). C’est pourquoi leelseest obligatoire.- Les nombres à virgule ont leurs propres opérations :
/.divise deux nombres à virgule, etfloat_of_inttransforme un entier en nombre à virgule.55 / 4donnerait l’entier13, et55 /. 4serait refusé, car55est un entier. - On appelle une fonction sans parenthèses ni virgules :
somme_et_nombre restecorrespond àsomme_et_nombre(reste)en Python. Les parenthèses servent seulement à regrouper :(moyenne_admis notes)forme un seul argument dePrintf.printf. let () = ...contient ce qui est exécuté au lancement du programme, comme le code placé en dehors des fonctions en Python.Printf.printfaffiche un texte ;%gmarque l’endroit où la moyenne s’insère, et\npasse à la ligne.- Dans une liste, les éléments sont séparés par des points-virgules :
[12; 7; 15; 9; 18; 10]. - La commande
ocamlexécute directement le fichier ; le compilateurocamloptpermet aussi d’en faire un fichier exécutable.
1(defun moyenne-admis (notes)
2 (let ((somme 0)
3 (nombre 0))
4 (dolist (note notes)
5 (when (>= note 10)
6 (setf somme (+ somme note))
7 (setf nombre (+ nombre 1))))
8 (/ somme nombre)))
9
10(let ((notes '(12 7 15 9 18 10)))
11 (format t "Moyenne des notes d'au moins 10 : ~a~%"
12 (float (moyenne-admis notes))))
Points communs avec Python
- Les mêmes étapes que la version en Python : deux variables qui comptent, une boucle sur les notes et une condition.
- Aucun type n’est écrit.
Particularités du langage Lisp
- Lisp, créé en 1958, est l’un des plus anciens langages encore utilisés. Son nom vient de l’anglais LISt Processing, « traitement de listes ». Cette version est écrite en Common Lisp, la forme standard du langage.
- Tout s’écrit entre parenthèses, sous forme de listes : le premier élément d’une liste est l’opération, les suivants sont ses arguments. On écrit donc
(+ somme note)au lieu desomme + note, et(>= note 10)au lieu denote >= 10: c’est la notation préfixée. - La définition de la fonction (
defun), la boucle (dolist) et la condition (when) sont elles aussi des listes : en Lisp, le code a la même forme que les données. letcrée les variablessommeetnombre, etsetfchange leur valeur :(setf somme (+ somme note))correspond àsomme = somme + note.- Les parenthèses délimitent les blocs ; l’indentation n’est pas obligatoire et sert seulement à rendre le code lisible.
(/ somme nombre)ne donne pas13.75mais la fraction exacte55/4: Lisp sait calculer avec des fractions.floatla transforme en nombre à virgule.- La dernière expression de la fonction donne la valeur renvoyée, sans
return. '(12 7 15 9 18 10)est une liste ; l’apostrophe indique qu’il s’agit de données, et non d’une opération à calculer.format taffiche un texte ;~amarque l’endroit où la valeur s’insère et~%passe à la ligne.
1(defn moyenne-admis [notes]
2 (let [admis (filter (fn [note] (>= note 10)) notes)]
3 (/ (reduce + admis) (count admis))))
4
5(let [notes [12 7 15 9 18 10]]
6 (println "Moyenne des notes d'au moins 10 :"
7 (double (moyenne-admis notes))))
Points communs avec Python
- Une fonction,
moyenne-admis, reçoit la liste des notes et renvoie la moyenne. - Aucun type n’est écrit.
countjoue le même rôle quelenen Python.
Particularités du langage Clojure
- Clojure, créé en 2007, est un langage de la famille de Lisp : on y retrouve les parenthèses et la notation préfixée (
(>= note 10),(+ somme note)). Il ajoute les crochets, qui servent à écrire les listes de paramètres ([notes]) et les vecteurs, l’équivalent des listes Python :[12 7 15 9 18 10], sans virgules. - Contrairement à la version en Lisp, il n’y a aucune boucle et aucune variable dont la valeur change : c’est le style fonctionnel, présenté plus bas. En Clojure, un vecteur ne se modifie jamais : on n’y ajoute pas d’élément, on fabrique un nouveau vecteur.
defnintroduit une fonction, commedefen Python ; ses paramètres sont écrits entre crochets.(fn [note] (>= note 10))est une fonction sans nom, écrite là où on l’utilise : elle reçoit une note et répondtruesi elle est supérieure ou égale à 10.filterapplique ce test à chaque note et ne garde que les notes pour lesquelles il répondtrue:(12 15 18 10).letdonne le nomadmisà ce résultat, sans pouvoir le changer ensuite.(reduce + admis)additionne les notes de proche en proche : 12 + 15, puis le résultat + 18, puis + 10, ce qui donne55. C’est l’équivalent desum(admis).- Comme en Lisp,
(/ 55 4)donne la fraction exacte55/4;doublela transforme en nombre à virgule. printlnaffiche ses arguments séparés par une espace, puis passe à la ligne, commeprinten Python.- Clojure fonctionne sur la machine virtuelle Java : la commande
clojuretraduit le programme en code intermédiaire, que la machine virtuelle exécute aussitôt (voir la section « Interpréter ou compiler », sous l’éditeur). Un programme Clojure peut donc utiliser toutes les bibliothèques écrites en Java.
1#!/bin/bash
2
3moyenne_admis() {
4 somme=0
5 nombre=0
6 for note in "$@"; do
7 if [ "$note" -ge 10 ]; then
8 somme=$((somme + note))
9 nombre=$((nombre + 1))
10 fi
11 done
12 echo "scale=2; $somme / $nombre" | bc
13}
14
15notes="12 7 15 9 18 10"
16echo "Moyenne des notes d'au moins 10 : $(moyenne_admis $notes)"
Points communs avec Python
- Une boucle
for note in ...et une conditionif. - Aucun type n’est écrit.
Particularités du langage Shell
- Le shell est le langage des commandes que l’on tape dans un terminal ; un fichier
.shenchaîne ces commandes. - Il ne sait calculer qu’avec des entiers :
$((somme + note))calcule une somme d’entiers. - La division à virgule est confiée à
bc, une commande qui sert de calculatrice ;scale=2lui demande deux chiffres après la virgule. Le signe|transmet àbcle texte produit parecho. - On écrit
somme=0, sans espace autour du signe=, pour donner une valeur à une variable, et$notepour lire la valeur de la variablenote. - Avant d’exécuter une ligne, le shell remplace
$notepar sa valeur, puis découpe le résultat en mots à chaque espace. Les guillemets ("$note","$@") empêchent ce découpage : chaque valeur reste entière, même si elle contient une espace. À l’inverse,moyenne_admis $notesest écrit sans guillemets, pour que le texte12 7 15 9 18 10soit découpé en six notes. -gesignifie « supérieur ou égal ».- Les blocs se terminent par des mots :
do ... donepour la boucle,if ... fipour la condition. - La fonction reçoit les notes séparées par des espaces ;
$@les désigne toutes.
1CREATE TABLE notes (note INTEGER);
2INSERT INTO notes VALUES (12), (7), (15), (9), (18), (10);
3
4SELECT 'Moyenne des notes d''au moins 10 : ' || AVG(note)
5FROM notes
6WHERE note >= 10;
Points communs avec Python
- La même condition
note >= 10.
Particularités du langage SQL
- SQL n’est pas un langage de programmation : c’est un langage de requêtes, qui sert à interroger une base de données, ici gérée par le logiciel SQLite.
- Les notes sont rangées dans une table, comme dans une feuille de tableur :
CREATE TABLEcrée la table avec une colonnenote, puisINSERTy ajoute six lignes. - La requête
SELECTne décrit aucune étape : elle décrit le résultat voulu.WHEREgarde les lignes qui vérifient la condition, etAVGcalcule leur moyenne. ||met deux textes bout à bout. À l’intérieur d’un texte, l’apostrophe est doublée (d''au) pour ne pas être confondue avec la fin du texte.
1<!DOCTYPE html>
2<html lang="fr">
3<head>
4 <meta charset="utf-8">
5 <title>Moyenne des notes</title>
6</head>
7<body>
8 <h1>Notes du trimestre</h1>
9 <ul>
10 <li>12</li>
11 <li>7</li>
12 <li>15</li>
13 <li>9</li>
14 <li>18</li>
15 <li>10</li>
16 </ul>
17 <p>Moyenne des notes d'au moins 10 : <strong>13.75</strong></p>
18</body>
19</html>
Points communs avec Python
- Aucun : HTML ne contient ni variable, ni condition, ni boucle.
Particularités du langage HTML
- HTML n’est pas un langage de programmation : c’est un langage de description, étudié dans le chapitre sur le Web. Il décrit le contenu d’une page, que le navigateur affiche.
- Les balises indiquent le rôle de chaque morceau de texte :
<h1>un titre,<ul>une liste,<li>un élément de liste,<p>un paragraphe,<strong>un passage mis en valeur. - HTML ne calcule rien : la moyenne
13.75a été écrite à la main. Pour la calculer dans la page, il faudrait ajouter un programme en JavaScript.
1<?php
2
3function moyenne_admis(array $notes): float
4{
5 $somme = 0;
6 $nombre = 0;
7 foreach ($notes as $note) {
8 if ($note >= 10) {
9 $somme = $somme + $note;
10 $nombre = $nombre + 1;
11 }
12 }
13 return $somme / $nombre;
14}
15
16$notes = [12, 7, 15, 9, 18, 10];
17echo "Moyenne des notes d'au moins 10 : " . moyenne_admis($notes) . "\n";
Points communs avec Python
- Les variables ne sont pas déclarées :
$somme = 0crée la variable, commesomme = 0. foreach ($notes as $note)parcourt directement les notes, commefor note in notes, mais le tableau est écrit avant la variable.functionintroduit une fonction, commedefen Python.
Particularités du langage PHP
- Le programme commence par
<?php, et chaque nom de variable commence par le signe$. - Le point
.colle deux textes bout à bout, comme+entre deux chaînes en Python.echoaffiche un texte, commeprint, mais sans passer à la ligne : il faut ajouter"\n". - Les types sont facultatifs :
array(un tableau) et: float(un nombre décimal) pourraient être supprimés. Quand ils sont écrits, PHP les vérifie au moment de l’exécution, et s’arrête sur une erreur si un argument n’a pas le bon type. - PHP sert surtout sur les serveurs web : le serveur exécute le programme, qui fabrique une page HTML, puis il envoie seulement cette page au navigateur. Le visiteur ne voit jamais le code PHP. Ici, la commande
phpexécute le programme dans un terminal.
1<!DOCTYPE html>
2<html lang="fr">
3<head>
4 <meta charset="utf-8">
5 <title>Moyenne des notes</title>
6</head>
7<body>
8 <p>Notes : <input id="notes" value="12 7 15 9 18 10"></p>
9 <button id="bouton">Calculer la moyenne</button>
10 <p id="resultat"></p>
11 <script>
12 function moyenneAdmis(notes) {
13 let somme = 0;
14 let nombre = 0;
15 for (const note of notes) {
16 if (note >= 10) {
17 somme = somme + note;
18 nombre = nombre + 1;
19 }
20 }
21 return somme / nombre;
22 }
23
24 function afficherMoyenne() {
25 const texte = document.getElementById("notes").value;
26 const notes = texte.split(" ").map(Number);
27 const resultat = document.getElementById("resultat");
28 const moyenne = moyenneAdmis(notes);
29 resultat.textContent = `Moyenne des notes d'au moins 10 : ${moyenne}`;
30 }
31
32 document.getElementById("bouton").addEventListener("click", afficherMoyenne);
33 </script>
34</body>
35</html>
Points communs avec Python
- Le calcul ne change pas : la fonction
moyenneAdmisest celle de la version JavaScript, elle-même très proche de la version Python. addEventListener("click", afficherMoyenne)joue le même rôle quecommand=afficherdans un bouton tkinter, vu dans le cours sur les interfaces graphiques : la fonction est appelée à chaque clic.
Particularités de la version événementielle
- Le programme ne s’exécute pas d’un bout à l’autre pour s’arrêter ensuite : il prépare des fonctions, les associe à des événements (un clic, une touche, le chargement de la page), puis attend. C’est le navigateur qui appelle la fonction quand l’événement se produit.
- Dans
addEventListener("click", afficherMoyenne), la fonction est écrite sans parenthèses : on ne l’appelle pas, on indique au navigateur laquelle appeler à chaque clic. document.getElementById("notes")désigne l’élément de la page dont l’attributidvautnotes. On lit le texte du champ avec.value, et on écrit le résultat dans le paragraphe vide avec.textContent.texte.split(" ")découpe le texte à chaque espace, et.map(Number)convertit chaque morceau en nombre, comme[float(m) for m in texte.split(" ")]en Python.- Dans l’aperçu, modifier les notes puis cliquer sur le bouton : la moyenne est recalculée. Si aucune note n’atteint 10, la division
0 / 0afficheNaN(en anglais, « pas un nombre ») : JavaScript continue là où Python s’arrêterait sur une erreur.
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:python3est 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
gccpour le C (gcc moyenne.c -o moyennecrée le fichier exécutablemoyenne, lancé par./moyenne),g++pour le C++ etrustcpour 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
notesde 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.
| Langage | Affectation | Condition | Boucle | Blocs | Types écrits |
|---|---|---|---|---|---|
| Python | somme = 0 | if note >= 10: | for note in notes: | indentation | non |
| C | int 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 |
| JavaScript | let somme = 0; | if (note >= 10) | for (const note of notes) | { } | non |
| TypeScript | let somme = 0; | if (note >= 10) | for (const note of notes) | { } | pour les paramètres et le résultat |
| Java | int somme = 0; | if (note >= 10) | for (int note : notes) | { } | oui |
| Go | somme := 0 | if note >= 10 | for _, note := range notes | { } | pour les paramètres et le résultat |
| Rust | let mut somme = 0; | if note >= 10 | for ¬e in notes | { } | pour les paramètres et le résultat |
| Kotlin | var somme = 0 | if (note >= 10) | for (note in notes) | { } | pour les paramètres et le résultat |
| Swift | var somme = 0 | if note >= 10 | for note in notes | { } | pour les paramètres et le résultat |
| Haskell | aucune variable modifiée | filter (>= 10) notes | aucune boucle | indentation | facultatifs (écrits ici) |
| OCaml | aucune variable modifiée | if note >= 10 then | aucune boucle (fonction récursive) | let ... in | non |
| Lisp | (let ((somme 0)) ...) | (when (>= note 10) ...) | (dolist (note notes) ...) | parenthèses | non |
| Clojure | aucune variable modifiée | (filter (fn [note] (>= note 10)) notes) | aucune boucle | parenthèses | non |
| Shell | somme=0 | if [ "$note" -ge 10 ] | for note in "$@" | do ... done | non |
| SQL | aucune | WHERE note >= 10 | aucune boucle | aucun | dans la table |
| HTML | aucune | aucune | aucune boucle | balises | non |
| 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.
| Langage | Domaines d’utilisation | Atouts | Limites |
|---|---|---|---|
| Python | enseignement, analyse de données, intelligence artificielle, petits programmes qui automatisent des tâches | syntaxe lisible et courte ; nombreuses bibliothèques pour le calcul, les graphiques et l’intelligence artificielle | exécution plus lente que celle d’un programme compilé ; erreurs de type découvertes seulement à l’exécution |
| C | systè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 processeurs | le 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 calcul | la rapidité du C, avec en plus les classes et une large bibliothèque standard | langage vaste et long à maîtriser ; mêmes risques liés à la mémoire qu’en C |
| JavaScript | pages web, dans le navigateur ; serveurs, avec Node.js | le langage de programmation des pages web : tous les navigateurs l’exécutent, sans rien installer | conversions de types surprenantes : "5" + 1 vaut "51" |
| TypeScript | applications web de grande taille | les types, vérifiés avant l’exécution, détectent beaucoup d’erreurs | une étape de compilation en plus ; les types ne sont plus vérifiés pendant l’exécution |
| Java | logiciels d’entreprise, serveurs, applications Android | le même fichier compilé fonctionne sur tous les systèmes, grâce à la machine virtuelle | code long à écrire : classes obligatoires et types écrits partout |
| Go | serveurs 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 facilement | langage volontairement réduit : moins de constructions que Python |
| Rust | logiciels où la sécurité compte : navigateurs, systèmes d’exploitation | aussi rapide que le C, mais le compilateur refuse les programmes qui utilisent mal la mémoire | apprentissage difficile : le compilateur refuse beaucoup de programmes |
| Kotlin | applications Android, recommandé par Google depuis 2019 | plus court à écrire que Java, et compatible avec les programmes Java | dépend de la machine virtuelle et des outils de Java |
| Swift | applications pour iPhone, iPad et Mac | rapide, et plus sûr que les langages qu’Apple utilisait avant lui | presque uniquement utilisé sur les appareils Apple |
| Haskell | recherche, quelques entreprises de la finance | style fonctionnel strict ; types très précis, vérifiés avant l’exécution | peu répandu dans les entreprises ; demande une autre façon de penser |
| OCaml | outils qui vérifient d’autres programmes, compilateurs, enseignement en classes préparatoires | types déduits et vérifiés avant l’exécution ; programmes rapides | communauté réduite, donc moins de bibliothèques |
| Lisp | intelligence 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 transformer | nombreuses parenthèses ; peu utilisé aujourd’hui |
| Clojure | serveurs 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 Java | démarrage lent, dû à la machine virtuelle Java ; messages d’erreur difficiles à lire |
| Shell | automatisation des tâches d’un ordinateur, administration des serveurs | enchaîne directement les commandes du terminal | mal adapté aux calculs et aux longs programmes ; règles pièges sur les espaces et les guillemets |
| SQL | bases de données des sites web, des banques, des administrations | on décrit le résultat voulu, et le logiciel de la base trouve lui-même comment l’obtenir | sert seulement à interroger et à modifier des bases de données |
| HTML | contenu des pages web | lu par tous les navigateurs | ne calcule rien ; l’apparence de la page est décrite à part, en CSS |
| PHP | sites 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ébergeurs | des 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.