Les langages de programmation ============================= langage Un langage de programmation doit permettre d'écrire des programmes de bonne qualité Un programme doit être : - correct - robuste - lisible, bien documenté - facile à modifier, extensible Un langage de programmation doit permettre : - la programmation structurée - la structuration avec les types - proposer un mécanisme d’exceptions - présenter des caractères de généricité, de polymorphisme et de surcharge .. important:: La structuration et l'organisation modulaire sert à maintenir de grands programmes, Elles sont une nécessité Approche historique et chronologique ------------------------------------- - Lambda calcul (1930) - machines de Turing (1936) - début des langages vers les années 1950 (A0, Fortran(impératif), Lisp(impératif et fonctionnel), Cobol) - années 60 : Simula (classes), CPL (compilation séparée) - années 70 : C (référence du langage impératif de bas niveau), Pascal (procédures), Smalltalk (programmation orientée objects), Prolog (programmation logique), Scheme (programmation fonctionnelle pure), Modula, C++, Ada, Turbo Pascal, Common Lisp, Eiffel (programmation par contrats) - années 80 : ML, CAML (langages fonctionnels) - années 90 : Perl, Python, Ruby (languages de scripting multi-paradigmes) Haskell (fonctionnel pur), Lua, Delphi, Java (orienté objet, machine virtuelle), PHP (impératif, dédié au web), Erlang (fonctionnel+ programmation concurrente), javascript (orienté web, objets par prototypage), OCaml (multi-paradigme, fortement typé, orienté sécurité, programmation générique, fonctionnelle et objets, modulaire et fonctorielle) - 2009 : go (google, compilé, typage statique, objets par prototypage, prgrammation concurrente), Rust (fondation mozilla, multiparadigme, programmation concurrente) Les langages actuellement les plus utilisés dans le monde de l'entreprise sont : - javascript/NodeJS (70% du code dans le dépôt github) mais victime de son succès (chaos complet des librairies) - le go est de plus en plus utilisé, c'est **le** langage qui monte actuellement - Python, Ruby, lua, autres langages de scripting (de plus en plus utilisés) - PHP, Java (stagnants) - C, C++ (de moins en moins utilisés) Approche par typologie des langages ----------------------------------- - **A0 (1954)** : possibilité de découpage de programmes en sous-programmes ; - **ALGOL (1958)** : concept de bloc de code (pas forcément nommé) et d'imbrication de blocs de code ; - **C (1971)** : syntaxe claire et simple, programme fortement structuré ; - **C (1980)** : le **code objet**, qui consiste à essayer de faire fonctionner un seul jeu d'instructions sur des machines différentes. Avant, le code d'assemblage dépendait du processeur, donc il n'y avait pas un seul et unique jeu d'instructions ; - **1980** : déploiement et succès des langages à objets ; - **1983** : turbo pascal (Borland) qui fut le tournant du C, propose un IDE (Environnement de Développement Intégré). aujourd'hui le turbo pascal a pratiquement disparu mais pas totalement, il est soutenu par une communauté open source autour de **Lazarus** ; - **depuis les années 90** : deux grands groupes de langages. Les langages à objets, et les langages fonctionnels. Les deux mondes s'interpénètrent (les avancées actuelles du web, les microservices (Erlang, Haskell), viennent du monde fonctionnel, le NoSQL, etc). Les grandes avancées architecturales (système d'exploitation, linux, etc...) viennent du monde de l'impératif. Approches par modèles de programmation -------------------------------------- - **le mécanisme d'exceptions** : il est possible de rompre l'exécution normale d'un programme à un endroit et de la reprendre à un autre endroit du programme prévu à cet effet. Ce mécanisme permet de gérer les situations exceptionnelles. - **le paradigme impératif** : les entrées-sorties, les modifications physiques de valeurs et les structures de contrôle itératives sont possibles. - **le paradigme fonctionnel** : manipule les fonctions comme étant des valeurs du langage. Celles-ci peuvent être utilisées en tant que paramètres d'autres fonctions ou être retournées comme résultat d'un appel de fonction. - **le paradigme objet** : La représentation du programme colle à la réalité en reproduisant des entités relativement proches des objets réel. Attention, le piège est de croire qu'il s'agit *du* paradigme universel puisqu'il reproduit en miroir le réel. **C'est en fait un processus d'abstraction comme un autre**. Sûreté du langage, typage ~~~~~~~~~~~~~~~~~~~~~~~~~ Tri par ordre de sûreté croissant : 0. typage très faible (presque inexistant aujourd'hui) : 42 == "42" == 42.0... 1. typage dynamique faible : (javascript) (possibilité de changer le prototype d'un objet pendant l'éxécution du programme, c'est la fête on peut faire n'importe quoi) 2. typage dynamique fort inféré par le comportement (behavior, duck typing) (python, ruby, PHP) Le contenu de la variable détermine le choix du typage `var = 0 -> type int` 3. typage statique déclaré fort (Java) `int var = 0 ;` (pas mal mais super lourd, pas **agile** du tout) 4. langages à types statiques muni d'un moteur d'inférence de types (Ocaml) sûreté d'exécution, agilité, sécurité. La syntaxe, la lisibilité ~~~~~~~~~~~~~~~~~~~~~~~~~ Importance de la lisibilité (notamment par rapport aux méthodes agiles). - courte (python) - verbeuse (C) - l'importance des mots clef du langage - délimiteur de phrase, de blocs (parenthèses, accolades, tabulations, blocs...) Langages compilés ou interprétés ? ----------------------------------- .. glossary:: langage compilé une première passe est faite, des validations son effectuées **avant** la génération du code objet, cette phase est faite par le compilateur. compilateur programme qui transforme un langage de haut niveau en un langage de base niveau - phase d’analyse syntaxique (source -> syntaxe abstraite) - phase de synthèse (syntaxe abstraite -> code objet) scripting (langage de scripting) langage interprèté générique (langage) Langage à usage générique, qui peut être utilisé dans n'importe quel domaine (par opposition au DSL) domain specific Domain Specific Language, langage destiné à être utilisé dans un domaine prédéfini. paradigmes représentation d'une vision particulière à partir d'un modèle théorique impératif l'algorithme ressemble à une recette de cuisine, c'est-à-dire à une succession d'instructions à exécuter les unes à la suite des autres fonctionnel l'algorithme ne dépend plus de l'ordre d'exécution d'instructions pas de mélange entre les données et les traitements objets (programmation) le monde est découpé en catégories qui permettent de créer des objets **développement par composants** les objets sont organisés entre eux par composants suivant des designs patterns, (patrons de conception) garbage collector (ramasse miettes) la gestion automatique de la mémoire apparaît en 1989 machine virtuelle portabilité du code (mais diminution en optimisation et performances) JIT (just in time compiler) code objet, programmes fonctionnant autour de machines virtuelles - **le typage statique** : la vérification de la compatibilité entre les types des paramètres formels et des paramètres d'appel est effectuée au moment de la compilation du programme. Dès lors, il n'est pas nécessaire de faire ces vérifications durant l'exécution du programme ce qui accroît son efficacité. En outre, la vérification de type permet d'éliminer la plupart des erreurs introduites par maladresse ou étourderie et contribue à la sûreté de l'exécution. - **le typage dynamique** : la vérification de la compatibilité entre les types des paramètres formels et des paramètres d'appel est effectuée au moment de l'exécution ou de l'appel à certaines parties de codes du programme. - **le polymorphisme paramétrique** : une fonction ou un objet qui n'explore pas la totalité de la structure d'un de ses arguments accepte que celui-ci ait un type non entièrement déterminé. Ce paramètre est alors dit polymorphe. Cette particularité permet de développer un code générique utilisable pour des structures de données différentes tant que la représentation exacte de cette structure n'a pas besoin d'être connue par le code en question. L'algorithme de typage est à même de faire cette distinction. - **l'inférence de types** : le programmeur n'a besoin de donner aucune information de type à l'intérieur de son programme. Le langage se charge seul de déduire du code le type le plus général des expressions et des déclarations qui y figurent. Cette inférence est effectuée conjointement à la vérification, lors de la compilation du programme. Les grands paradigmes de programmation --------------------------------------- Le paradigme des objets ~~~~~~~~~~~~~~~~~~~~~~~ - 1962 (SIMULA) : premières notions de classes ; Pui, une dizaine d'années plus tard : - C++ : intégration des classes pour le C ; - turbo pascal : intégration des classes pour le pascal ; Tous les langages actuels ont intégré des traits objets mais de manière très différentes : - perl (1987) - python (1991) - Ruby (1993) - L'implémentation des objets en python est très proche des notions initiales de classes issues du Smaltalk et présente une tentative très intéressante d'unification des objets et des types depuis python 2.2 ; - Java (1995) : très grosse réussite industrielle en surfant sur la vague de la programmation objet, et des machines virtuelles, mais en fait et avec le recul, doté d'un support objet lourd et alambiqué. Le monde Java est lourd, avec des outils consommant beaucoup de mémoire et qui ne satisfont pas à la règle du KISS (Keep It Simple, Stupid) ; Il n'y a pas **une** POO (Programmation Objet), il y a des POO. Les implémentations objets dans les langages sont riches et variées : - objets obligatoirement construits pas des classes (Java, C++, ...) - objets sans définition de classes (javascript, Ocaml, go, rust) - langages à attributs (python) - langages ou le type des objets est défini par leur classe (python, ruby) - langages ou le type des objets est différent du type de leur classe (Ocaml) - objets sans classes mais construits par des prototypes (javascript) - construction d'objets possibles objets sans classe du tout (Ocaml) - encapsulation des attributs des objets (Java, Ocaml, C++, PHP) - pas d'encapsulation des attributs (python, ruby, javascript...) Le paradigme impératif ~~~~~~~~~~~~~~~~~~~~~~ Un programme est une suite d'états de la mémoire de l'ordinateur, c'est la suite logique des machines de Turing. La plupart des programmeur aujourd'hui raisonnent suivant ce paradigme, et ont une très faible visibilité par rapport aux autres paradigmes existants. Seuls les programmeurs cultivés sont aujourd'hui capable de raisonner suivant différents paradigmes, ce sont des programmeurs chevronnés et cultivés. Le paradigme fonctionnel ~~~~~~~~~~~~~~~~~~~~~~~~ La notion de fonction que possède sous une forme ou une autre la plupart des langages est empruntée aux mathématiques et non à l'électronique. D'une manière générale, les langages substituent des modèles formels aux conceptions purement calculatoires. Ils y gagnent en expressivité. Certains langages fondent leur paradigme de programmation sur l'abstraction entrée-traitement-sortie, donc sur le **mathème fonctionnel** et pas sur la boite noire électronique. La fonction mathématique apporte un niveau opératoire dans le traitement de l'information. Approche par fonctionnalités ---------------------------- Plusieurs domaines de l'informatique on proposé/imposé des méthodologies, des manières de faire. Ces modèles de programmation on fortement influencé en retour les langages. On reconnaît aujourd'hui : - Le modèle client-serveur - Le modèle de programmation concurrente (exécution de processus légers, threads) : - Le modèle de développement d'une application de bureau (MVC, ergonomie d'interface) - Le modèle de développement web (communiquer sur le réseau Internet, API REST, microservices...) - Le modèle de programmation système et réseau - le modèle **Dev Ops** et les méthodes de développement virtualisés - les langages présentant des **fonctionnalités agiles** Conclusion ----------- Les langages de haut niveau sont caractérisés par des concepts tels que : - déclaration de valeurs, types, expressions, portée - expressions, variables, instructions, structures de contrôle - fonctions, procédures, fermetures - encapsulation, modules, objets =========== ============ Paradigmes Concepts =========== ============ impératif variables, procédures, modules objets classes, méthodes, héritage, surcharge fonctionnel fonctions, fermetures, modules logique prédicats, modules concurrent tâche/processus, communication =========== ============