langage de programmation qui offre une forte abstraction des détails techniques de l' ordinateur . Contrairement aux langages de bas niveau , il peut utiliser des éléments du langage naturel , être plus facile à utiliser, ou automatiser (voire masquer entièrement) des aspects importants des systèmes informatiques (par exemple, la gestion de la mémoire ), ce qui rend le développement d'un programme plus simple et plus compréhensible qu'avec un langage de bas niveau. Le degré d'abstraction proposé définit le « haut niveau » d'un langage de programmation.
Le terme « haut niveau » désigne un niveau d'abstraction par rapport aux détails matériels d'un processeur inhérents au code machine et au code assembleur . Au lieu de manipuler des registres, des adresses mémoire et des piles d'appels, les langages de haut niveau utilisent des variables, des tableaux, des objets , des expressions arithmétiques et booléennes , des fonctions , des boucles, des threads , des verrous et d'autres abstractions informatiques, afin de garantir la correction et la maintenabilité du code. Contrairement aux langages assembleur de bas niveau , les langages de haut niveau comportent peu, voire aucun, élément de langage directement traduisible en opcodes natifs de la machine . D'autres fonctionnalités, telles que la manipulation de chaînes de caractères, la programmation orientée objet et les entrées/sorties de fichiers, peuvent également être disponibles. Un langage de haut niveau permet d'écrire un code source indépendant des détails matériels de la machine. Autrement dit, contrairement aux langages de bas niveau comme l'assembleur et le code machine, le code de haut niveau peut entraîner des transferts de données à l'insu du programmeur. Le compilateur conserve une certaine maîtrise des instructions à exécuter.
code machine ou en langage assembleur , reflétant fidèlement le jeu d'instructions d'une machine donnée. Les langages de programmation de haut niveau se sont développés pour exprimer les algorithmes sous des formes plus proches des mathématiques, des règles métier ou des procédures lisibles par l'humain, tandis qu'un compilateur ou un interpréteur traduisait le programme en instructions exécutables par la machine. Dans les années 1950 et 1960, le terme « autocode » était souvent employé pour désigner les langages de haut niveau basés sur un compilateur ; on peut citer comme exemples les premiers systèmes Autocode ainsi que des langages tels que Fortran et COBOL .Le premier langage de haut niveau conçu pour un ordinateur est généralement identifié comme Plankalkül , développé par Konrad Zuse dans les années 1940. Il comprenait des fonctionnalités avancées telles que les données structurées, l'affectation, l'exécution conditionnelle, l'itération et les sous-programmes, mais il n'a pas été implémenté du vivant de Zuse. Comme Zuse travaillait dans l'Allemagne de la guerre et de l'après-guerre, ses travaux sont restés largement isolés du courant principal du développement des langages, bien qu'ils aient influencé le Superplan de Heinz Rutishauser et, dans une moindre mesure, les premiers travaux associés à ALGOL .
Le premier langage de haut niveau à connaître une large adoption pratique fut Fortran , développé chez IBM dans les années 1950 sous la direction de John Backus . Fortran était destiné au calcul scientifique et numérique, permettant aux programmeurs d'écrire des formules algébriques et des boucles sans avoir à gérer manuellement chaque instruction machine. Son succès a contribué à démontrer que les langages compilés de haut niveau pouvaient produire des programmes efficaces tout en réduisant considérablement l'effort de programmation.
Plusieurs autres langages influents sont apparus à la même époque. Lisp , créé par John McCarthy , a introduit le traitement symbolique des listes et a placé les concepts du lambda-calcul au cœur de la conception pratique des langages de programmation. COBOL a été conçu pour le traitement des données d'entreprise et s'est associé à une syntaxe proche de l'anglais, aux enregistrements et aux applications commerciales orientées fichiers. La famille ALGOL , et plus particulièrement ALGOL 60 , a influencé la conception ultérieure des langages grâce à sa structure par blocs, ses procédures imbriquées, sa récursivité, sa portée lexicale, la distinction entre appel par valeur et appel par nom, et l'utilisation de la forme de Backus-Naur pour définir formellement la syntaxe.
Dans les années 1960 et 1970, les langages de haut niveau se sont diversifiés en différents styles de programmation. Le BASIC a rendu la programmation interactive accessible dans les environnements à temps partagé et éducatifs, tandis que le Pascal privilégiait la programmation structurée et l'enseignement. Le C combinait des structures de contrôle de haut niveau avec un accès relativement bas niveau à la mémoire et au matériel, ce qui lui a valu une grande influence dans les systèmes d'exploitation et les logiciels système . Simula a introduit le modèle classe - objet , devenu central dans la programmation orientée objet , et Smalltalk a par la suite développé cette même programmation autour de l'échange de messages et d'un environnement de programmation hautement interactif.
Dans les années 1980 et 1990, le développement des langages de haut niveau reflétait de plus en plus l'ingénierie logicielle à grande échelle, l'informatique graphique et l'essor d'Internet. Ada a été conçu pour les systèmes de grande envergure et à longue durée de vie, notamment dans les domaines de la défense et des systèmes embarqués. C++ a étendu C avec des classes et d'autres mécanismes d'abstraction, permettant la programmation orientée objet et générique tout en conservant les capacités de programmation système. Les langages de script et d'application rapide tels que Perl , Python , Ruby et PHP ont mis l'accent sur la productivité des programmeurs et le développement de scripts textuels, web ou applicatifs. Java a favorisé l'exécution portable de bytecode grâce à la machine virtuelle Java , tandis que JavaScript est devenu le langage de script de haut niveau standard des navigateurs web .
Au XXIe siècle, les nouveaux langages de haut niveau se sont souvent concentrés sur une abstraction plus sûre, la concurrence, les vastes bases de code et l'interopérabilité avec les plateformes existantes. C# a été développé en parallèle de la plateforme .NET , Scala et F# ont combiné programmation orientée objet et fonctionnelle, et Kotlin visait l'interopérabilité avec Java tout en ajoutant une syntaxe concise et une gestion des valeurs nulles. Go a été conçu pour une syntaxe simple, une compilation rapide et une prise en charge native de la concurrence. Rust a mis l'accent sur la sécurité de la mémoire et des threads sans utiliser de ramasse-miettes, tandis que Swift a été introduit comme un langage moderne pour le développement de logiciels sur la plateforme Apple. TypeScript a étendu JavaScript avec un typage statique pour les applications JavaScript à grande échelle.
Pénalité d'abstraction
Un langage de haut niveau offre des fonctionnalités qui standardisent les tâches courantes, permettent un débogage avancé et préservent l'indépendance architecturale. À l'inverse, un langage de bas niveau exige du programmeur qu'il travaille à un niveau d'abstraction inférieur, généralement plus complexe, mais permettant des optimisations impossibles avec un langage de haut niveau. Ce surcoût d'abstraction lié à l'utilisation d'un langage de haut niveau est réel, mais en pratique, les optimisations de bas niveau améliorent rarement les performances au niveau de l' expérience utilisateur . Néanmoins, un code devant s'exécuter rapidement et efficacement peut nécessiter l'utilisation d'un langage de bas niveau, même si un langage de haut niveau simplifierait l'écriture et la maintenance du code. Dans de nombreux cas, des parties critiques d'un programme, écrites principalement dans un langage de haut niveau, sont codées en assembleur afin de respecter des contraintes strictes de temps d'exécution ou de mémoire. Un compilateur bien conçu pour un langage de haut niveau peut produire un code d'une efficacité comparable à celle d'un code assembleur écrit à la main, et les abstractions de haut niveau permettent parfois des optimisations qui surpassent les performances de l'assembleur écrit à la main. Puisqu'un langage de haut niveau est conçu indépendamment d'une architecture de système informatique spécifique , un programme écrit dans un tel langage peut s'exécuter sur n'importe quel environnement informatique disposant d'un compilateur ou d'un interpréteur compatible.
Contrairement à un langage de bas niveau, intrinsèquement lié au matériel du processeur, un langage de haut niveau peut être amélioré. De nouveaux langages de haut niveau peuvent ainsi émerger d'autres langages, l'objectif étant de regrouper les constructions les plus populaires et d'y intégrer des fonctionnalités améliorées. Par exemple, Scala assure la rétrocompatibilité avec Java . Le code écrit en Java reste utilisable même si un développeur passe à Scala. Cela facilite la transition et prolonge la durée de vie du code . À l'inverse, les programmes de bas niveau survivent rarement au-delà de l' architecture système pour laquelle ils ont été conçus.
Signification relative
Le langage C prend en charge des constructions telles que l'évaluation d'expressions, les fonctions paramétrées et récursives, les types de données et les structures qui ne sont généralement pas pris en charge en assembleur ni directement par un processeur. Le C offre néanmoins des fonctionnalités de bas niveau comme l'auto-incrémentation et les calculs sur les pointeurs. Cependant, il lui manque de nombreuses abstractions de haut niveau courantes dans d'autres langages, telles que le ramasse-miettes et un type chaîne de caractères intégré. Dans l'introduction de *The C Programming Language * (deuxième édition) de Brian Kernighan et Dennis Ritchie , le C est décrit comme un langage « de niveau relativement faible ».
Le langage assembleur est de plus haut niveau que le code machine, mais reste fortement dépendant du matériel du processeur. Il peut toutefois offrir certaines fonctionnalités de plus haut niveau telles que les macros , des expressions relativement limitées, des constantes, des variables, des procédures et des structures de données .
Le code machine se situe à un niveau d'abstraction légèrement supérieur au microcode ou aux micro-opérations utilisés en interne dans de nombreux processeurs.
Modes d'exécution
- Transpilé
- Le code peut être traduit en code source d'un autre langage (généralement de plus bas niveau) pour lequel un compilateur ou un interpréteur est disponible. JavaScript et le C sont des cibles courantes pour ces traducteurs. Par exemple, le code C et C++ peut être visualisé comme étant généré à partir du code Eiffel lors de l'utilisation de l' EDI EiffelStudio . Dans Eiffel, le processus de traduction est appelé transcompilation , et le compilateur Eiffel, transcompilateur ou compilateur source-à-source .
- Logiciel interprété
- Un interpréteur logiciel exécute les actions encodées dans le code source sans générer de code machine natif.
- Interprétation matérielle
- Bien que peu courant, un processeur doté d'une architecture informatique de langage de haut niveau peut traiter un langage de haut niveau sans étape de compilation programmée.
Il est important de noter qu'un langage n'est pas strictement interprété ou compilé. En réalité, un modèle d'exécution fait intervenir un compilateur ou un interpréteur, et un même langage peut être utilisé avec différents modèles d'exécution. Par exemple, ALGOL 60 et Fortran ont tous deux été interprétés, bien qu'ils soient généralement compilés. De même, Java illustre la difficulté d'appliquer ces étiquettes aux langages plutôt qu'à leurs implémentations. Java est compilé en bytecode, qui est ensuite exécuté soit par interprétation dans une machine virtuelle Java (JVM), soit par compilation JIT.