Informatique et Sciences du Numérique au lycée : un pas plus loin/LANGAGES/Éléments de syntaxe et de sémantique/Styles de Programmation

Un livre de Wikilivres.

Les langages de programmation sont nombreux (plusieurs milliers) mais ont souvent, au moins théoriquement, la même puissance d'expression, celles des langages dits Turing-complets. Ces langages diffèrent déjà par le niveau de programmation considéré, depuis les langages dits de bas niveau, c'est-à-dire proches du langage machine, jusqu'aux langages dits de haut niveau pour lesquels une instruction correspond à une suite d'instructions machine. Les langages de haut niveau se distinguent aussi par leur style de programmation, c'est-à-dire la manière d'exprimer l'algorithme et les données à manipuler. Certains langages sont particulièrement ou même exclusivement dédiés à un certain type d'applications : langages dédiés au temps réel, aux bases de données, aux échanges sur le web, etc.

Dans le style applicatif, Un programme est vu comme le calcul de la valeur d'une expression à partir de celles de ses sous-expressions. Il fait donc tout naturellement appel à la notion de fonction mathématique et les algorithmes y sont souvent exprimés de manière récursive. Ce style est adopté en particulier par tous les langages dits fonctionnels, tels que Ocaml, Haskell, Lisp, Spec-sharp, etc.

Dans le style impératif, un programme est vu comme une suite de changements de l'état-mémoire au moyen d'instructions, et notamment de l'affectation. La valeur d'une expression dépend non seulement des valeurs des sous-expressions, mais aussi de l'état courant de la mémoire : il n'y a pas de transparence référentielle. Les algorithmes y sont souvent exprimés à l'aide de boucles. Ce style est adopté en particulier par tous les langages dits impératifs, comme C, Pascal, Fortran, Ada, etc.

Dans le style orienté-objet, un programme est vu comme l'interaction de briques logicielles appelées objets. Un objet modélise un concept, une entité du monde physique. Il possède une structure interne et un comportement et il sait interagir avec ses pairs. L'interaction entre les objets via leurs relations permet de concevoir et réaliser les fonctionnalités attendues du programme. Ce style est adopté en particulier par les langages dits objet ou à classes ou acteurs comme C++, Java, Smalltalk, etc. Voir la page Programmation orientée objet.

La plupart des langages de programmation récents comme Ocaml, Python, Fsharp permettent d'utiliser conjointement ces trois styles.

Le style logique diffère profondément des précédents en ce qu'un programme décrit le résultat attendu à partir d'un ensemble de faits (hypothèses avérées) et de règles de déduction. Le langage fournit un moteur qui applique ces règles de déduction aux hypothèses pour en déduire de nouveaux faits et ultimement le résultat. Ce style est adopté par les langages comme Prolog, etc.

Les langages cités plus haut sont pour la plupart des langages dits ''séquentiels'' au sens où un programme est conçu comme une succession d'actions (calculs, modifications de l'état mémoire) jusqu'à obtention du résultat. Ils offrent donc l'instruction de séquence ( le <code>;</code>) et l'appel de fonctions pour décrire cette succession. Les langages dits ''parallèles'' permettent de décrire les communications entre sous-systèmes qui interagissent en permanence et proposent donc des constructions syntaxiques de ''composition parallèle'' de programmes.

Concernant la conception de l'exécution proprement dite, deux points sont à considérer : d'une part, l'ordonnancement des calculs, d'autres part, l'interaction avec un environnement physique. Pour l'ordonnancement, l'exécution d'un programme peut être vue soit comme une séquence d'instructions, une seule étant exécutée à la fois, soit comme un ensemble de séquences d'instructions pouvant être effectuées en même temps. On parle de programmation séquentielle dans le premier cas et de programmation parallèle dans le second cas. Tous les langages permettent la programmation séquentielle. Certains langages ne fournissent aucun outil pour la programmation parallèle. La plupart des langages récents offrent de tels outils, le parallèlisme pouvant être géré totalement de manière explicite par le programmeur ou au contraire géré directement par le compilateur, l'entrelacement des suites d'exécution restant implicite dans le programme. La programmation parallèle est déclinée en différentes approches selon le niveau auquel est fait l'entrelacement des instructions : le niveau processus sur un seul processeur avec la programmation concurrente, le niveau processus exécutés sur plusieurs processeurs (éventuellement en grille ou en grappe) avec la programmation distribuée. L'interaction avec un environnement physique demande de gérer le temps et la durée de la communication avec cet environnement, qui peut se faire par exemple par des capteurs, des échanges de message, etc. La communication peut parfois se faire sans contrainte temporelle particulière : la transmission de données s'effectue selon le rythme de production des résultats ou d'acquisition des données. En revanche dans les systèmes temps-réel dits à temps contraint ou très contraint, les délais de transmission sont imposés par l'environnement et doivent être impérativement respectés. Par exemple, le freinage d'un train doit être effectué dans un laps de temps imposé par la conception même du train et du signal reçu. On parle alors de programmation temps-réel, qui existe en deux versions. Dans la programmation dite asynchrone, les contraintes de temps sont gérées directement par le programmeur; Dans la programmation synchrone, elles sont gérées par le langage lui-même via un calcul d'horloge. Voir Programmation dédiée temps réel


Programmation concurrente