programmation informatique definition

Qu’est-ce que la programmation informatique ? Définition

La programmation informatique peut être considérées comme l’art d’écrire des instructions pour qu’une machine, typiquement un ordinateur, puisse exécuter des tâches spécifiques. Mais au-delà de cette définition simple, il existe une riche histoire, une évolution constante des méthodes, et une multitude de façons de penser la programmation, appelées « paradigmes ». Plongeons-nous dans ce monde fascinant.

Origines et histoire de la programmation informatique

L’aspiration de l’homme à automatiser des tâches en utilisant des machines a une histoire ancienne, qui précède de loin l’émergence des ordinateurs tels que nous les connaissons aujourd’hui. Le concept fondamental de programmation (donner à une machine un ensemble d’instructions pour exécuter une tâche spécifique) a ses racines au 19ème siècle.

Au milieu du 19ème siècle, Charles Babbage, un mathématicien et inventeur anglais, a conçu ce que l’on pourrait appeler le précurseur de l’ordinateur moderne : la « machine analytique ». Bien que Babbage ait rencontré de nombreux défis, notamment financiers, qui ont empêché la réalisation complète de son invention, l’idée sous-jacente était révolutionnaire. Cette machine était conçue pour être mécanique et utilisait des cartes perforées, inspirées par le métier à tisser Jacquard, pour recevoir ses instructions.

Ada Lovelace, fille du célèbre poète Lord Byron, a été introduite à Babbage et à ses inventions. Fascinée par le potentiel de la machine analytique, elle s’est engagée dans une étude approfondie de son fonctionnement. Ada a non seulement traduit un article du mathématicien italien Luigi Federico Menabrea sur la machine, mais elle a également ajouté ses propres notes et commentaires. Ces ajouts, bien plus volumineux que l’article original, contenaient ce que beaucoup considèrent comme le tout premier algorithme destiné à être traité par une machine, faisant d’elle la première programmeuse de l’histoire.

L’élan initial posé par Babbage et Lovelace a été repris au 20ème siècle avec l’avènement des machines électromécaniques, puis électroniques. Ces premiers ordinateurs, comme le Colossus en 1943, l’ENIAC en 1945 ou encore le UNIVAC I en 1951, étaient des géants en comparaison avec les normes actuelles, mais ils ont marqué le début de l’ère informatique. Avec ces nouvelles machines, est apparue la nécessité impérieuse de développer des langages et des méthodes pour les programmer.

Le milieu du 20ème siècle a été témoin de l’émergence d’une multitude de langages de programmation, comme le Fortran en 1957, qui a révolutionné la programmation scientifique, ou le COBOL en 1959, conçu pour la programmation commerciale. Chaque nouveau langage offrait des perspectives et des outils innovants pour aborder les défis computationnels, ouvrant la voie à l’explosion technologique que nous observons aujourd’hui.

Les paradigmes de programmation

On appelle « paradigme » ce qui est un style ou une approche fondamentale de la programmation. Chaque paradigme offre une perspective unique sur la façon de résoudre les problèmes. Voici un aperçu des paradigmes les plus influents :

La programmation impérative

La programmation impérative est l’un des premiers paradigmes de programmation qui a été développé, et elle continue d’être l’une des approches les plus prédominantes dans le monde de la programmation. Au cœur de ce paradigme se trouve l’idée que les programmes sont conçus comme une suite linéaire d’instructions, chacune indiquant à l’ordinateur une action spécifique à réaliser. Ces instructions sont exécutées l’une après l’autre, de manière séquentielle, exactement comme elles sont écrites dans le code source. Cette séquentialité est une représentation directe de la manière dont les premiers ordinateurs étaient conçus pour fonctionner. Les machines recevaient des commandes, les exécutaient et passaient à la commande suivante. Cela reflète une pensée très mécanique et directe de la computation. Dans l’esprit de nombreux programmeurs, cela rend la programmation impérative intuitive, car elle suit une logique « cause à effet ». Chaque instruction est comme un ordre donné à l’ordinateur : « Fais ceci, puis cela, ensuite cela… ».

De nombreux langages de programmation populaires, comme le C, le Pascal ou le Fortran, sont fortement ancrés dans le paradigme impératif. Ils permettent aux développeurs de décrire explicitement chaque étape que la machine doit suivre pour arriver à un résultat souhaité. Toutefois, il est essentiel de noter que la programmation impérative n’est pas seulement une série d’instructions, elle implique également la gestion des états. Les variables sont utilisées pour stocker et manipuler les données tout au long de l’exécution d’un programme. Les changements d’état, tels que la modification de la valeur d’une variable, sont fondamentaux dans cette approche.

La programmation procédurale

C’est en soi une évolution naturelle et logique de la programmation impérative. Elle s’appuie sur les fondements de l’impératif tout en introduisant des mécanismes pour structurer et organiser le code de manière plus efficace et lisible. Cette structuration est obtenue grâce à l’introduction de routines ou fonctions, qui permettent de regrouper plusieurs instructions en un bloc unique, pouvant être invoqué à volonté. Imaginez la programmation impérative comme raconter une histoire où chaque détail est décrit à chaque fois. La programmation procédurale, en revanche, est comme créer un lexique de ces détails, permettant au narrateur de se référer simplement au lexique au lieu de re-décrire chaque élément. Ce lexique, dans le contexte de la programmation, est constitué de procédures et de fonctions.

L’introduction de ces fonctions offre plusieurs avantages. Tout d’abord, elle permet de réduire la redondance dans le code. Si une action ou une série d’actions doit être effectuée plusieurs fois, elle peut être encapsulée dans une fonction et simplement appelée chaque fois que nécessaire. Cela rend également le code plus lisible et plus facile à maintenir. Si une modification doit être apportée à cette série d’actions, il suffit de modifier la fonction plutôt que chaque instance de cette action dans le code. Des langages comme le C, le COBOL et le FORTRAN ont adopté ce paradigme et l’ont popularisé. Par exemple, le C offre une vaste bibliothèque standard de fonctions, permettant aux programmeurs d’accomplir des tâches courantes sans avoir à réinventer la roue à chaque fois. Le COBOL, utilisé principalement dans le domaine commercial, a également permis d’organiser des tâches financières et administratives complexes en séquences procédurales pour garantir efficacité et précision.

En outre, et pour en terminer sur elle, la programmation procédurale met l’accent sur la séparation entre les données et les procédures qui les manipulent. Cela conduit à une meilleure organisation du code et à une distinction claire entre la logique métier et les structures de données.

La programmation en langage C est ancienne

La programmation structurée

Née dans les années 70, la programmation structurée est le fruit d’une prise de conscience grandissante dans la communauté des développeurs : un code bien organisé est plus facile à comprendre, à maintenir et à déboguer. Cette approche va au-delà de la simple introduction de routines ou de fonctions, comme le fait la programmation procédurale. Elle met l’accent sur la manière dont ces fonctions interagissent entre elles et comment les flux de contrôle sont gérés au sein du programme.

L’un des grands tournants de cette approche a été l’abandon progressif de l’instruction « goto », longtemps utilisée pour contrôler le flux d’exécution d’un programme. Bien que puissant, « goto » a souvent conduit à ce qu’on appelle le « code spaghetti » (un code difficile à suivre et à maintenir en raison de sa structure chaotique). La programmation structurée prône l’utilisation de structures de contrôle plus intuitives comme les boucles (for, while) et les conditions (if, else), offrant une vision claire de l’exécution du programme, facilitant ainsi sa compréhension et son évolution.

La programmation déclarative

La programmation déclarative repose sur une philosophie radicalement différente de celle de la programmation impérative ou procédurale. Au lieu de décrire étape par étape comment atteindre un résultat, comme un chef d’orchestre guidant chaque mouvement de ses musiciens, la programmation déclarative se contente de définir ce que l’on souhaite obtenir, laissant le soin au « système » de déterminer la meilleure façon d’y parvenir. C’est un peu comme commander un plat dans un restaurant : vous choisissez le plat que vous voulez déguster sans vous soucier de la recette exacte ou de la méthode de cuisson.

Cette abstraction du « comment » conduit à des codes étonnamment expressifs et concis. En se concentrant sur le « quoi », la programmation déclarative permet aux développeurs de réduire le bruit, d’éliminer les détails superflus et de mettre en lumière l’essence même du problème. Ce niveau d’expression élevé offre également une plus grande flexibilité, car les spécifications peuvent être satisfaites de différentes manières, selon les optimisations ou les évolutions des systèmes sous-jacents.

La programmation fonctionnelle

La programmation fonctionnelle puise ses racines dans les concepts fondamentaux des mathématiques et au cœur de cette approche, nous retrouvons les fonctions, entités pures qui, pour une entrée donnée, produisent toujours la même sortie sans provoquer d’effets secondaires. En d’autres termes, une fonction ne dépend que de ses arguments et ne modifie pas l’état externe ou les variables en dehors de sa portée. Cela conduit à une propriété essentielle de la programmation fonctionnelle : l’immutabilité. Une fois qu’une structure de données est créée, elle ne peut être modifiée. Si une transformation est nécessaire, une nouvelle structure est générée.

Cette perspective offre de nombreux avantages. L’immutabilité garantit une plus grande prévisibilité du code, réduit les erreurs courantes liées aux effets secondaires et facilite le parallélisme, car les données ne sont pas modifiées « en place », ce qui élimine le risque de conflits d’accès concurrentiels.

Des langages comme LISP, avec sa syntaxe minimaliste et sa capacité à traiter le code comme des données, et Scala, qui fusionne les paradigmes fonctionnels et orientés objet, sont emblématiques de cette approche. Ils incarnent les principes fondamentaux de la programmation fonctionnelle et offrent des mécanismes pour créer des applications efficaces, robustes et expressives.

Néanmoins, face aux avantages incontestables de la programmation fonctionnelle, de nombreux langages « traditionnels » n’ont pas hésité à intégrer certains de ses principes. Java, par exemple, a introduit les expressions lambda et les streams dans ses versions récentes, permettant aux développeurs d’adopter des styles fonctionnels dans un environnement autrefois majoritairement impératif. Cette fusion des paradigmes montre l’impact durable et l’attrait de la programmation fonctionnelle dans le paysage informatique contemporain.

La programmation logique

Elle constitue une approche où le raisonnement domine le processus de programmation. Plutôt que de se concentrer sur une séquence d’instructions à exécuter, comme c’est le cas dans les paradigmes impératifs ou procéduraux, la programmation logique s’articule autour de la formulation de déclarations (ou prédicats) qui décrivent des relations, des faits ou des règles. Ces déclarations forment une base de connaissances que le système utilisera pour déduire logiquement des solutions ou des réponses.

Prenons un exemple simple : si nous avons un prédicat déclarant que « tous les hommes sont mortels » et un autre affirmant que « Socrate est un homme », la programmation logique permettrait de déduire, à partir de ces deux déclarations, que « Socrate est mortel ». Le programme n’a pas besoin d’être explicitement instruit sur la manière de tirer cette conclusion ; il utilise la logique pour arriver à cette déduction.

Le langage Prolog est l’un des représentants les plus emblématiques de cette approche. Dans Prolog, le développeur définit une série de faits et de règles, et le moteur d’exécution se charge d’interroger cette base pour trouver des réponses ou résoudre des problèmes. Cela donne lieu à des programmes très différents de ce que l’on retrouve dans les approches impératives, car ils ressemblent davantage à des collections de déclarations qu’à des séquences d’instructions.

Cette approche est particulièrement puissante pour les problèmes qui nécessitent des déductions, des résolutions de problèmes complexes ou la manipulation de connaissances. Cependant, elle demande une certaine adaptation pour les programmeurs habitués aux paradigmes plus classiques, car elle repose sur une manière différente de penser et d’aborder les problèmes.

La programmation orientée objet (ou POO)

La programmation orientée objet, couramment abrégée POO, a révolutionné la manière dont les développeurs conçoivent et structurent leur code. Cette approche nous invite à voir le monde de la programmation à travers le prisme des « objets », des entités qui encapsulent à la fois des données (attributs) et des comportements (méthodes).

Le cœur de la POO : Classes et Objets

La base de la POO repose sur le concept de « classe ». Une classe est comme un blueprint ou un moule à partir duquel des objets sont créés. Elle définit un ensemble d’attributs (qui décrivent l’état) et de méthodes (qui définissent les actions). Ainsi, si nous prenons l’exemple d’une classe « Voiture », les attributs pourraient être « couleur » ou « marque », et les méthodes pourraient être « démarrer » ou « klaxonner ».

Un « objet » est une instance concrète de cette classe et si nous poursuivons avec l’exemple de la voiture, un objet particulier pourrait être une voiture de couleur rouge de la marque Ferrari. Chaque fois qu’une nouvelle instance est créée, elle possède ses propres valeurs d’attributs, mais partage les comportements définis par la classe.

Encapsulation, Héritage et Polymorphisme

Au-delà de la simple définition des classes et des objets, la POO introduit des concepts puissants déjà évoqués ici comme :

  • L’encapsulation : Il s’agit de cacher les détails internes d’un objet et de n’exposer que ce qui est nécessaire. Cela protège l’intégrité des données et facilite la gestion de la complexité.
  • L’héritage : Les classes peuvent hériter de propriétés et de comportements d’autres classes, permettant une réutilisation de code et une structuration hiérarchique.
  • Le polymorphisme : Il permet à un objet de prendre plusieurs formes. Par exemple, une classe « Oiseau » peut avoir une méthode « chanter », mais la manière dont un rossignol et un corbeau chantent peut être différente. Grâce au polymorphisme, chaque oiseau peut implémenter cette méthode à sa manière.

La POO a influencé de nombreux langages modernes tels que Java, C++, Python ou Ruby. Elle offre une approche naturelle pour modéliser et résoudre des problèmes, en alignant le monde du logiciel plus étroitement sur le monde réel, où tout est, en essence, un objet interagissant avec d’autres objets.

La programmation en Ruby est elle récente (Standardisé au Japon en 2011)

Programmation orientée prototype

La programmation orientée prototype, souvent perçue comme un sous-ensemble ou une variante de la programmation orientée objet, propose une vision différente et plus souple de la création et de l’interaction des objets. Plutôt que de se baser sur le modèle classique des classes et des instances, elle privilégie la création d’objets par clonage direct à partir d’autres objets, appelés prototypes.

L’absence de la hiérarchie de classes

Contrairement à la programmation orientée objet classique, où une classe sert de plan ou de modèle pour créer des objets, la programmation orientée prototype ne requiert pas de telles définitions formelles. Un prototype est un objet complet en soi, qui peut être dupliqué ou étendu pour créer de nouveaux objets. Cette flexibilité permet de créer et de modifier des objets à la volée, sans avoir à redéfinir ou à ajuster des classes entières.

L’héritage basé sur les prototypes

L’une des caractéristiques essentielles de la programmation orientée prototype est sa capacité à permettre l’héritage sans l’intervention de classes. Lorsqu’un objet est cloné à partir d’un prototype, il hérite des attributs et des comportements de cet objet original. Si un attribut ou une méthode n’est pas trouvé sur l’objet, le système remonte la chaîne de prototypes jusqu’à ce qu’il trouve ce qu’il cherche ou jusqu’à ce qu’il atteigne le prototype de base.

Flexibilité et dynamisme

La possibilité de cloner et d’ajouter ou de modifier des attributs et des méthodes sur des objets individuels offre une grande souplesse. Cela signifie également que les objets peuvent évoluer dynamiquement en fonction des besoins, sans nécessiter de modifications structurelles importantes ou de redéfinitions. JavaScript est ici l’un des langages de programmation les plus connus qui utilise ce paradigme. Dans JavaScript, tous les objets peuvent servir de prototypes pour d’autres objets, permettant une approche dynamique et flexible de la création d’objets et de l’héritage.

La programmation orientée classe

La programmation orientée classe, pour finir, est un pilier essentiel du monde numérique ; Elle est basée principalement sur la notion de « classe », servant de blueprint pour la création d’objets. Ces classes définissent les attributs et les méthodes des objets, comme ceux d’une « Voiture » qui comprendrait des informations telles que la marque et des fonctions comme démarrer. Des concepts centraux tels que l’encapsulation, qui protège les données de l’objet, l’héritage, permettant à une nouvelle classe d’emprunter des attributs d’une classe existante, et la polymorphie, qui favorise la flexibilité du code, façonnent ce paradigme. De nombreux langages modernes comme Java ou Python s’appuient sur cette approche, rendant la conception de logiciels plus structurée, robuste et maintenable.

Chaque paradigme a ses propres avantages, ses inconvénients et ses cas d’utilisation idéaux. Certains langages de programmation sont strictement liés à un paradigme, tandis que d’autres offrent la flexibilité d’en utiliser plusieurs ainsi que vous avez pu le constater dans ce sujet. De même, en fonction des fins, on s’orientera largement vers tel type de programmation ou tel autre, on ne construit évidemment pas un site Web vitrine comme un logiciel.

R.C.