formations/algorithmique/cours/langage.txt

221 lines
10 KiB
Plaintext
Raw Normal View History

Les langages de programmation
=============================
Approche historique et chronologique
-------------------------------------
- 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 ?
-----------------------------------
- **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) ;
Les supports objets sont riches et variés,
- 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**