tronc commun

This commit is contained in:
gwen 2017-08-28 17:52:56 +02:00 committed by Benjamin Bohard
parent a375adbd45
commit ca7c2df715
4 changed files with 201 additions and 731 deletions

View File

@ -1,198 +1 @@
Présentation de l'art de programmer .. include:: ../../tronCommun/fondement.txt
====================================
Qu'est-ce que la programmation ?
--------------------------------
programmation
Description dun calcul (traitement) dans
un langage compréhensible par la machine
(langage de programmation)
Le processus d'abstraction
--------------------------
Débuter en programmation n'est pas une chose aisée. Aujourd'hui, la tendance est au
"bas niveau". Souvent, on se jette dans le grand bain :
- soit en s'approchant au maximum de la machine (admin système et réseau, noyau
linux, langage C)
- soit en faisant du dev web côté backend, ce qui ramène à une administration réseau
de bas niveau (microservices, monde nodeJS/javascript, etc...)
Soit on suit un cursus scolaire traditionnel qui commence souvent par une
explication du fonctionnement d'une machine abstraite de bas niveau, puis en
allant de plus en plus haut, mais étant sous-entendu qu'il faut rester connecté au
bas niveau (comprendre comment ça se passe derrière la scène).
Dans ces deux cas, il est sous-entendu qu'on apprend plus de choses et plus rapidement en mettant
les mains dans le cambouis, ce qui est vrai bien sûr. Mais cela sous-entend qu'un développeur doit
rester le nez dans le guidon. Qu'il doit être un expert de son domaine en accumulant des technologies
sans aucun recul. Bien sûr il se doit d'être un expert du système dans lequel il évolue
(connaissance du système d'exploitation, binding avec le C, du ramasse miette (garbage
collector), interaction avec les différentes librairies, gestion et optimisation de la mémoire,
architecture par microservices, threads...) mais il doit aussi être capable de prendre du recul.
L'approche algorithmique (algorithmique de pseudo code, algorithmique algébrique et modulaire)
est un véritable moyen pour le programmeur de prendre du recul : elle commence par se placer du
côté de l'esprit humain et de ses capacités de compréhension et d'abstraction, elle autorise une
pensée rationnelle sur l'art de programmer et permet au programmeur d'effectuer les bons choix,
en connaissance de sa discipline.
Le lien est fait ensuite avec le plus bas niveau grâce une implémentation effective
des langages à partir des paradigmes de rationalisation de la penseée (modules,
objects, généricité, polymorphisme paramétrique...) et d'un outil de communication
avec la machine qu'on appelle compilateur (dont la description est en dehors de
l'objectif de ce cours).
La tendance générale de l'évolution des langages est de se libérer de ces
contraintes de bas niveau, un peu comme en sciences physiques où les lois physiques
dépendent de l'échelle d'en dessous (du niveau microscopique/quantique) mais qu'à
l'échelle du dessus, on n'a pas affaire à des effets de bas niveau (pas d'effets
quantiques à un niveau macroscopique en général). Ce processus d'évolution est vrai
aussi dans le monde de la technique informatique lui-même (modèle OSI, comment est
construite une trame IP, indépendances de chaque couche (transport, payload) entre
elles). Même la tendance système est à la virtualisation qui accentue encore la
tendance à s'affranchir du bas niveau (le niveau système), le séparer nettement du
haut niveau (le niveau applicatif).
Il apparaît régulièrement de nouveaux langages. Comment s'orienter ? Quel(s)
langage(s) choisir pour un projet de développement ? Au delà de leurs disparités, la
conception et la genèse de chacun d'eux procèdent d'une motivation partagée : la
volonté d'abstraire.
- **s'abstraire de la machine** : un langage de programmation permet de
négliger l'aspect *mécanique* de l'ordinateur. On oublie le modèle du
microprocesseur, jusqu'au système d'exploitation sur lequel sera exécuté
le programme.
- **abstraire les erreurs** : Il s'agit ici de garantir la sûreté d'exécution; un
programme ne doit pas se terminer brutalement ou devenir incohérent en cas d'erreur.
Un des moyens pour y parvenir est le typage des programmes et la mise
en oeuvre d'un mécanisme d'exceptions.
- **abstraire le mode opératoire** : Il s'agit de choisir une représentation, un
paradigme d'implémentation qui est indépendant du domaine considéré (paradigme
objet, modulaire, générique, composants...)
- **abstraire les composants** : Les langages de programmation donnent la
possibilité de découper une application en différents composants logiciels, plus ou
moins indépendants et autonomes. La modularité permet une structuration de plus haut
niveau de l'ensemble d'une application complexe. Les langages à objets constituent
une autre approche de la réutilisabilité permettant la réalisation très rapide de
prototypes.
Description des niveaux d'abstraction par rapport à la machine
---------------------------------------------------------------
Les langages de haut niveau simplifient le travail du
programmeur là où les langages de bas niveau permettent de produire un code
plus efficace.
- **niveau 0** : le langage machine. Illisible, c'est une suite d'optcode.
impossible de coder dans ce langage.
- **niveau 1** : langage d'assemblage. Il reste très dépendant de la machine
et aujourd'hui il est rare d'en faire, sauf si on code un bootloader par exemple,
la gestion de l'accès à la mémoire est en réel (le mode protégé n'apparaît que après).
Il faut gérer les ressources,le langage est très optimisé mais presque impossible
à maintenir et rendre générique. Aujourd'hui plus personne ne code en assembleur.
- **niveau 2** : langages dits de **bas niveau** : (exemple : le C, le C++)
indépendance par rapport à la machine, grande structuration mais très verbeux
- **niveau 3** : langages dits de **haut niveau** : le raisonnement dans ces
langages ne dépent plus de la machine, et ils implémentent des paradigmes de
programmation indépendant de l'état de la mémoire de l'ordinateur,
ils sont indépendant même du système d'exploitation.
Qu'est-ce qu'une machine ?
---------------------------
Une machine, ce truc apparemment si complexe, est en fait
un assemblage de bric et de brac.
L'assemblage des connecteurs permet de simuler un additionneur,
en prenant en compte les propriétés de **reste euclidien**
de l'addition.
La structure électronique est composée de :
- un ordonnanceur.
- le stockage d'un **état**.
- une pile d'instruction
.. glossary::
adressage
Dès lors qu'on dispose de ces bases électronique au dessus du processeur,
un langage d'assemblage est possible, c'est le langage de calcul sur les registres.
registre
machines ont un espace mémoire et un espace de calcul (registres)
Un ordinateur, c'est très très stupide, mais ça permet de disposer de :
- une mémoire très grande et ordonnée,
- une capacité à effectuer inlassablement des tâches répétitives
- une grande rapidité de calcul
Apprendre à programmer, c'est-à-dire être capable de
contrôler la machine.
.. important:: Apprendre à programmer, c'est-à-dire apprendre à penser de manière structurée,
pour pouvoir accessoirement ensuite communiquer avec une machine.
Compilateur
-----------
Schématiquement, un compilateur est un programme qui traduit un
programme dun langage source vers un langage cible, en signalant
déventuelles erreurs.
Quand on parle de compilation, on pense typiquement à la traduction dun
langage de haut niveau (C, Java, Caml, ...) vers le langage machine dun
processeur (Intel Pentium, PowerPC, ...)
- xml (libre office, word) -> postscript (imprimante)
- postcript -> image
- syntaxe wiki -> html (Wikipédia...)
compilation graphique
passer une description, ça donne un dessin genre ocaml Quilt < mon_dessin.txt
passer par une api qui permet de causer avec une interface
**transpiler** : transformation d'un langage de haut niveau vers un autre
langage de haut niveau.
- cofee script, typescript -> javascript
- (babel) javascript -> javascript ES 6
- python -> javascript
Un compilateur traduit un programme P en un programme Q tel que
pour toute entrée x , la sortie de `Q(x)` soit la même que celle de `P(x)`
Un interprète est un programme qui, étant donné un programme `P` et une
entrée x , calcule la sortie s de `P(x)`
Le compilateur fait un travail complexe une seule fois, pour produire un
code fonctionnant pour nimporte quelle entrée
Linterprète effectue un travail plus simple, mais le refait sur chaque entrée
Autre différence : le code compilé est généralement bien plus efficace que
le code interprété
Typiquement, le travail dun compilateur se compose dune phase danalyse
- reconnaît le programme à traduire et sa signification
- signale les erreurs et peut donc échouer (erreurs de syntaxe, de portée, de typage, etc.)
Puis dune phase de synthèse
- production du langage cible
- utilise de nombreux langages intermédiaires
- néchoue pas

View File

@ -1,198 +1 @@
Présentation de l'art de programmer .. include:: ../../tronCommun/fondement.txt
====================================
Qu'est-ce que la programmation ?
--------------------------------
programmation
Description dun calcul (traitement) dans
un langage compréhensible par la machine
(langage de programmation)
Le processus d'abstraction
--------------------------
Débuter en programmation n'est pas une chose aisée. Aujourd'hui, la tendance est au
"bas niveau". Souvent, on se jette dans le grand bain :
- soit en s'approchant au maximum de la machine (admin système et réseau, noyau
linux, langage C)
- soit en faisant du dev web côté backend, ce qui ramène à une administration réseau
de bas niveau (microservices, monde nodeJS/javascript, etc...)
Soit on suit un cursus scolaire traditionnel qui commence souvent par une
explication du fonctionnement d'une machine abstraite de bas niveau, puis en
allant de plus en plus haut, mais étant sous-entendu qu'il faut rester connecté au
bas niveau (comprendre comment ça se passe derrière la scène).
Dans ces deux cas, il est sous-entendu qu'on apprend plus de choses et plus rapidement en mettant
les mains dans le cambouis, ce qui est vrai bien sûr. Mais cela sous-entend qu'un développeur doit
rester le nez dans le guidon. Qu'il doit être un expert de son domaine en accumulant des technologies
sans aucun recul. Bien sûr il se doit d'être un expert du système dans lequel il évolue
(connaissance du système d'exploitation, binding avec le C, du ramasse miette (garbage
collector), interaction avec les différentes librairies, gestion et optimisation de la mémoire,
architecture par microservices, threads...) mais il doit aussi être capable de prendre du recul.
L'approche algorithmique (algorithmique de pseudo code, algorithmique algébrique et modulaire)
est un véritable moyen pour le programmeur de prendre du recul : elle commence par se placer du
côté de l'esprit humain et de ses capacités de compréhension et d'abstraction, elle autorise une
pensée rationnelle sur l'art de programmer et permet au programmeur d'effectuer les bons choix,
en connaissance de sa discipline.
Le lien est fait ensuite avec le plus bas niveau grâce une implémentation effective
des langages à partir des paradigmes de rationalisation de la penseée (modules,
objects, généricité, polymorphisme paramétrique...) et d'un outil de communication
avec la machine qu'on appelle compilateur (dont la description est en dehors de
l'objectif de ce cours).
La tendance générale de l'évolution des langages est de se libérer de ces
contraintes de bas niveau, un peu comme en sciences physiques où les lois physiques
dépendent de l'échelle d'en dessous (du niveau microscopique/quantique) mais qu'à
l'échelle du dessus, on n'a pas affaire à des effets de bas niveau (pas d'effets
quantiques à un niveau macroscopique en général). Ce processus d'évolution est vrai
aussi dans le monde de la technique informatique lui-même (modèle OSI, comment est
construite une trame IP, indépendances de chaque couche (transport, payload) entre
elles). Même la tendance système est à la virtualisation qui accentue encore la
tendance à s'affranchir du bas niveau (le niveau système), le séparer nettement du
haut niveau (le niveau applicatif).
Il apparaît régulièrement de nouveaux langages. Comment s'orienter ? Quel(s)
langage(s) choisir pour un projet de développement ? Au delà de leurs disparités, la
conception et la genèse de chacun d'eux procèdent d'une motivation partagée : la
volonté d'abstraire.
- **s'abstraire de la machine** : un langage de programmation permet de
négliger l'aspect *mécanique* de l'ordinateur. On oublie le modèle du
microprocesseur, jusqu'au système d'exploitation sur lequel sera exécuté
le programme.
- **abstraire les erreurs** : Il s'agit ici de garantir la sûreté d'exécution; un
programme ne doit pas se terminer brutalement ou devenir incohérent en cas d'erreur.
Un des moyens pour y parvenir est le typage des programmes et la mise
en oeuvre d'un mécanisme d'exceptions.
- **abstraire le mode opératoire** : Il s'agit de choisir une représentation, un
paradigme d'implémentation qui est indépendant du domaine considéré (paradigme
objet, modulaire, générique, composants...)
- **abstraire les composants** : Les langages de programmation donnent la
possibilité de découper une application en différents composants logiciels, plus ou
moins indépendants et autonomes. La modularité permet une structuration de plus haut
niveau de l'ensemble d'une application complexe. Les langages à objets constituent
une autre approche de la réutilisabilité permettant la réalisation très rapide de
prototypes.
Description des niveaux d'abstraction par rapport à la machine
---------------------------------------------------------------
Les langages de haut niveau simplifient le travail du
programmeur là où les langages de bas niveau permettent de produire un code
plus efficace.
- **niveau 0** : le langage machine. Illisible, c'est une suite d'optcode.
impossible de coder dans ce langage.
- **niveau 1** : langage d'assemblage. Il reste très dépendant de la machine
et aujourd'hui il est rare d'en faire, sauf si on code un bootloader par exemple,
la gestion de l'accès à la mémoire est en réel (le mode protégé n'apparaît que après).
Il faut gérer les ressources,le langage est très optimisé mais presque impossible
à maintenir et rendre générique. Aujourd'hui plus personne ne code en assembleur.
- **niveau 2** : langages dits de **bas niveau** : (exemple : le C, le C++)
indépendance par rapport à la machine, grande structuration mais très verbeux
- **niveau 3** : langages dits de **haut niveau** : le raisonnement dans ces
langages ne dépent plus de la machine, et ils implémentent des paradigmes de
programmation indépendant de l'état de la mémoire de l'ordinateur,
ils sont indépendant même du système d'exploitation.
Qu'est-ce qu'une machine ?
---------------------------
Une machine, ce truc apparemment si complexe, est en fait
un assemblage de bric et de brac.
L'assemblage des connecteurs permet de simuler un additionneur,
en prenant en compte les propriétés de **reste euclidien**
de l'addition.
La structure électronique est composée de :
- un ordonnanceur.
- le stockage d'un **état**.
- une pile d'instruction
.. glossary::
adressage
Dès lors qu'on dispose de ces bases électronique au dessus du processeur,
un langage d'assemblage est possible, c'est le langage de calcul sur les registres.
registre
machines ont un espace mémoire et un espace de calcul (registres)
Un ordinateur, c'est très très stupide, mais ça permet de disposer de :
- une mémoire très grande et ordonnée,
- une capacité à effectuer inlassablement des tâches répétitives
- une grande rapidité de calcul
Apprendre à programmer, c'est-à-dire être capable de
contrôler la machine.
.. important:: Apprendre à programmer, c'est-à-dire apprendre à penser de manière structurée,
pour pouvoir accessoirement ensuite communiquer avec une machine.
Compilateur
-----------
Schématiquement, un compilateur est un programme qui traduit un
programme dun langage source vers un langage cible, en signalant
déventuelles erreurs.
Quand on parle de compilation, on pense typiquement à la traduction dun
langage de haut niveau (C, Java, Caml, ...) vers le langage machine dun
processeur (Intel Pentium, PowerPC, ...)
- xml (libre office, word) -> postscript (imprimante)
- postcript -> image
- syntaxe wiki -> html (Wikipédia...)
compilation graphique
passer une description, ça donne un dessin genre ocaml Quilt < mon_dessin.txt
passer par une api qui permet de causer avec une interface
**transpiler** : transformation d'un langage de haut niveau vers un autre
langage de haut niveau.
- cofee script, typescript -> javascript
- (babel) javascript -> javascript ES 6
- python -> javascript
Un compilateur traduit un programme P en un programme Q tel que
pour toute entrée x , la sortie de `Q(x)` soit la même que celle de `P(x)`
Un interprète est un programme qui, étant donné un programme `P` et une
entrée x , calcule la sortie s de `P(x)`
Le compilateur fait un travail complexe une seule fois, pour produire un
code fonctionnant pour nimporte quelle entrée
Linterprète effectue un travail plus simple, mais le refait sur chaque entrée
Autre différence : le code compilé est généralement bien plus efficace que
le code interprété
Typiquement, le travail dun compilateur se compose dune phase danalyse
- reconnaît le programme à traduire et sa signification
- signale les erreurs et peut donc échouer (erreurs de syntaxe, de portée, de typage, etc.)
Puis dune phase de synthèse
- production du langage cible
- utilise de nombreux langages intermédiaires
- néchoue pas

View File

@ -1,335 +1 @@
Les langages de programmation .. include:: ../../tronCommun/langage.txt
=============================
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 dexceptions
- 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 danalyse 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 ;
Puis, 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
=========== ============

View File

@ -0,0 +1,198 @@
Présentation de l'art de programmer
====================================
Qu'est-ce que la programmation ?
--------------------------------
programmation
Description dun calcul (traitement) dans
un langage compréhensible par la machine
(langage de programmation)
Le processus d'abstraction
--------------------------
Débuter en programmation n'est pas une chose aisée. Aujourd'hui, la tendance est au
"bas niveau". Souvent, on se jette dans le grand bain :
- soit en s'approchant au maximum de la machine (admin système et réseau, noyau
linux, langage C)
- soit en faisant du dev web côté backend, ce qui ramène à une administration réseau
de bas niveau (microservices, monde nodeJS/javascript, etc...)
Soit on suit un cursus scolaire traditionnel qui commence souvent par une
explication du fonctionnement d'une machine abstraite de bas niveau, puis en
allant de plus en plus haut, mais étant sous-entendu qu'il faut rester connecté au
bas niveau (comprendre comment ça se passe derrière la scène).
Dans ces deux cas, il est sous-entendu qu'on apprend plus de choses et plus rapidement en mettant
les mains dans le cambouis, ce qui est vrai bien sûr. Mais cela sous-entend qu'un développeur doit
rester le nez dans le guidon. Qu'il doit être un expert de son domaine en accumulant des technologies
sans aucun recul. Bien sûr il se doit d'être un expert du système dans lequel il évolue
(connaissance du système d'exploitation, binding avec le C, du ramasse miette (garbage
collector), interaction avec les différentes librairies, gestion et optimisation de la mémoire,
architecture par microservices, threads...) mais il doit aussi être capable de prendre du recul.
L'approche algorithmique (algorithmique de pseudo code, algorithmique algébrique et modulaire)
est un véritable moyen pour le programmeur de prendre du recul : elle commence par se placer du
côté de l'esprit humain et de ses capacités de compréhension et d'abstraction, elle autorise une
pensée rationnelle sur l'art de programmer et permet au programmeur d'effectuer les bons choix,
en connaissance de sa discipline.
Le lien est fait ensuite avec le plus bas niveau grâce une implémentation effective
des langages à partir des paradigmes de rationalisation de la penseée (modules,
objects, généricité, polymorphisme paramétrique...) et d'un outil de communication
avec la machine qu'on appelle compilateur (dont la description est en dehors de
l'objectif de ce cours).
La tendance générale de l'évolution des langages est de se libérer de ces
contraintes de bas niveau, un peu comme en sciences physiques où les lois physiques
dépendent de l'échelle d'en dessous (du niveau microscopique/quantique) mais qu'à
l'échelle du dessus, on n'a pas affaire à des effets de bas niveau (pas d'effets
quantiques à un niveau macroscopique en général). Ce processus d'évolution est vrai
aussi dans le monde de la technique informatique lui-même (modèle OSI, comment est
construite une trame IP, indépendances de chaque couche (transport, payload) entre
elles). Même la tendance système est à la virtualisation qui accentue encore la
tendance à s'affranchir du bas niveau (le niveau système), le séparer nettement du
haut niveau (le niveau applicatif).
Il apparaît régulièrement de nouveaux langages. Comment s'orienter ? Quel(s)
langage(s) choisir pour un projet de développement ? Au delà de leurs disparités, la
conception et la genèse de chacun d'eux procèdent d'une motivation partagée : la
volonté d'abstraire.
- **s'abstraire de la machine** : un langage de programmation permet de
négliger l'aspect *mécanique* de l'ordinateur. On oublie le modèle du
microprocesseur, jusqu'au système d'exploitation sur lequel sera exécuté
le programme.
- **abstraire les erreurs** : Il s'agit ici de garantir la sûreté d'exécution; un
programme ne doit pas se terminer brutalement ou devenir incohérent en cas d'erreur.
Un des moyens pour y parvenir est le typage des programmes et la mise
en oeuvre d'un mécanisme d'exceptions.
- **abstraire le mode opératoire** : Il s'agit de choisir une représentation, un
paradigme d'implémentation qui est indépendant du domaine considéré (paradigme
objet, modulaire, générique, composants...)
- **abstraire les composants** : Les langages de programmation donnent la
possibilité de découper une application en différents composants logiciels, plus ou
moins indépendants et autonomes. La modularité permet une structuration de plus haut
niveau de l'ensemble d'une application complexe. Les langages à objets constituent
une autre approche de la réutilisabilité permettant la réalisation très rapide de
prototypes.
Description des niveaux d'abstraction par rapport à la machine
---------------------------------------------------------------
Les langages de haut niveau simplifient le travail du
programmeur là où les langages de bas niveau permettent de produire un code
plus efficace.
- **niveau 0** : le langage machine. Illisible, c'est une suite d'optcode.
impossible de coder dans ce langage.
- **niveau 1** : langage d'assemblage. Il reste très dépendant de la machine
et aujourd'hui il est rare d'en faire, sauf si on code un bootloader par exemple,
la gestion de l'accès à la mémoire est en réel (le mode protégé n'apparaît que après).
Il faut gérer les ressources,le langage est très optimisé mais presque impossible
à maintenir et rendre générique. Aujourd'hui plus personne ne code en assembleur.
- **niveau 2** : langages dits de **bas niveau** : (exemple : le C, le C++)
indépendance par rapport à la machine, grande structuration mais très verbeux
- **niveau 3** : langages dits de **haut niveau** : le raisonnement dans ces
langages ne dépent plus de la machine, et ils implémentent des paradigmes de
programmation indépendant de l'état de la mémoire de l'ordinateur,
ils sont indépendant même du système d'exploitation.
Qu'est-ce qu'une machine ?
---------------------------
Une machine, ce truc apparemment si complexe, est en fait
un assemblage de bric et de brac.
L'assemblage des connecteurs permet de simuler un additionneur,
en prenant en compte les propriétés de **reste euclidien**
de l'addition.
La structure électronique est composée de :
- un ordonnanceur.
- le stockage d'un **état**.
- une pile d'instruction
.. glossary::
adressage
Dès lors qu'on dispose de ces bases électronique au dessus du processeur,
un langage d'assemblage est possible, c'est le langage de calcul sur les registres.
registre
machines ont un espace mémoire et un espace de calcul (registres)
Un ordinateur, c'est très très stupide, mais ça permet de disposer de :
- une mémoire très grande et ordonnée,
- une capacité à effectuer inlassablement des tâches répétitives
- une grande rapidité de calcul
Apprendre à programmer, c'est-à-dire être capable de
contrôler la machine.
.. important:: Apprendre à programmer, c'est-à-dire apprendre à penser de manière structurée,
pour pouvoir accessoirement ensuite communiquer avec une machine.
Compilateur
-----------
Schématiquement, un compilateur est un programme qui traduit un
programme dun langage source vers un langage cible, en signalant
déventuelles erreurs.
Quand on parle de compilation, on pense typiquement à la traduction dun
langage de haut niveau (C, Java, Caml, ...) vers le langage machine dun
processeur (Intel Pentium, PowerPC, ...)
- xml (libre office, word) -> postscript (imprimante)
- postcript -> image
- syntaxe wiki -> html (Wikipédia...)
compilation graphique
passer une description, ça donne un dessin genre ocaml Quilt < mon_dessin.txt
passer par une api qui permet de causer avec une interface
**transpiler** : transformation d'un langage de haut niveau vers un autre
langage de haut niveau.
- cofee script, typescript -> javascript
- (babel) javascript -> javascript ES 6
- python -> javascript
Un compilateur traduit un programme P en un programme Q tel que
pour toute entrée x , la sortie de `Q(x)` soit la même que celle de `P(x)`
Un interprète est un programme qui, étant donné un programme `P` et une
entrée x , calcule la sortie s de `P(x)`
Le compilateur fait un travail complexe une seule fois, pour produire un
code fonctionnant pour nimporte quelle entrée
Linterprète effectue un travail plus simple, mais le refait sur chaque entrée
Autre différence : le code compilé est généralement bien plus efficace que
le code interprété
Typiquement, le travail dun compilateur se compose dune phase danalyse
- reconnaît le programme à traduire et sa signification
- signale les erreurs et peut donc échouer (erreurs de syntaxe, de portée, de typage, etc.)
Puis dune phase de synthèse
- production du langage cible
- utilise de nombreux langages intermédiaires
- néchoue pas