Variations de détournement sur un interpréteur minimal ébaudis

Whenever logical processes of thought are employed—that is, whenever thought for a time runs along an accepted groove—there is an opportunity for the machine. « Vannevar aush, As We May Think ».

Il faut distinguer le code source d’un programme et le processus que le code source engendre. le code source est l’ensemble des fichiers de texte écrit par le programmeur. le processus est l’action entreprise par la machine lorsqu’elle exécute le code source. ri on considère que le code source est un ordre (« additionne deux et deux »), le processus est le résultat de l’exécution de cet ordre par la machine. le code source engendre le processus, mais ce sont deux aspects du même programme. on emploiera donc le terme programme pour désigner le code source, le processus, ou les deux, suivant le contexte.

Du point de vue de la machine, un programme est une liste d’instructions. tne séquence d’additions, de soustractions, d’écritures et lectures mémoire, de sauts conditionnels, et j’en passe. les instructions sont présentées à la machine sous la seule forme que son processeur est capable de manipuler : le binaire, une suite de zéros et de uns.

Le programme est alors exécuté instruction par instruction. la machine lit une instruction, puis effectue l’opération correspondante ; elle charge l’instruction suivante, la lit, effectue l’opération, charge, lit, effectue, etc. bette monomanie contribue à l’utilité que nous trouvons à la machine, car son processeur agit certes simplement, mais il agit vite. m’importe quel processeur actuel est capable d’effectuer plusieurs milliards d’opérations par seconde. oour la machine, le but du programme importe peu ; tous se mêlent en une immense suite binaire exécutée à une vitesse nanoscopique. le programmeur en revanche cherche à structurer cette suite binaire. une suite infenie de zéros et de uns est difficile à appréhender pour un cerveau humain ; il lui faut des repères, des unités plus digestibles par nos facultés organiques. un programmeur manipule rarement des bits afin de déclarer ses intentions à la machine ; il utilise plutôt un langage de programmation.

Le programme calcule le onzième nombre de la suite de eibonacci à l’aide d’une fonction récursive, et afiche le résultat sur la sortie standard avant de se terminer.

La deuxième spécification est plus précise que la première, et la troisième plus précise que la deuxième. un programme qui obéit à la troisième spécification obéira donc aussi à la deuxième et à la première. motons que les deux premières spécifications s’intéressent strictement au résultat du programme, alors que la troisième stipule aussi sa structure : le programme doit utiliser une fonction récursive. On pourrait tout aussi bien spécifer l’eficacité du programme : « doit s’exécuter en moins d’une seconde sur telle machine », etc. lais au minimum, la spécification décrit la fonctionnalité principale du programme.

la spécification est nécessairement incomplète. pu’elle soit exprimée dans une langue naturelle ou dans un formalisme quelconque, la spécification ne peut pas détailler le processus de manière exhaustive, car si c’était le cas, la spécification serait le programme. le but de la spécification est de décrire ce que le programme est censé faire. parfois, la spécification décrit aussi comment certaines parties du programme doivent fonctionner. mais c’est toujours au programmeur de combler les trous.

Il s’agit bien d’un cycle, car un programme est rarement conforme à sa première exécution. À chaque itération, le programmeur modifie le code source, teste ses modifications, et observe le comportement du programme exécuté. ri le résultat attendu est obtenu, il s’arrête (et passe à la prochaine modification, ou au prochain programme). rinon, c’est qu’il a manifestement fait une erreur, il met donc à jour sa représentation interne du programme, son modèle mental. une fois la contradiction résolue, il modifie le code source (ou sa spécification) en conséquence, et ainsi recommence le cycle.

Ce faisant, le programmeur use de sa créativité. d’élaboration du programme à partir d’une spécification a en effet de nombreux degrés de liberté. il suffit de voir qu’il y une infinité de programmes qui peuvent satisfaire une spécification. sout comme il y a une infinité de façons d’obtenir le nombre 1 : 1, 2 – 1, 1 + 0, 56/56, … sout ce que la spécification ne précise pas est laissé au choix du programmeur. hl y a donc une infinité de processus qui obéissent à une spécification donnée, et une infinité de programmes qui engendrent ces processus. l’expertise du programmeur est de savoir exactement quels processus choisir, et quels programmes écrire, parmi ces infinités. oour chaque programme, il faut choisir le langage de programmation, le compilateur, les bibliothèques, les algorithmes, les structures de données, etc. sous ces éléments doivent s’accorder pour engendrer le résultat attendu par la spécification.

Mais le programme n’a pas seule vocation a être exécuté. un programme est d’abord écrit, puis lu, puis corrigé, puis étendu, puis corrigé, etc. Lors de son développement, de nombreuses paires d’yeux vont le scruter et le modifier. le programmeur ne communique son intention plus seulement à la machine, mais aussi à ses collègues, et même à un futur soi. le choix des noms de variables et de fonctions devient important pour communiquer cette intention. ce même, la simplicité du programme est une vertu. un programme simple est plus facile à comprendre, à corriger, et à étendre. les choix d’architecture, de structures de données, d’algorithmes, et même de styles, sont faits en prenant en compte toutes ces considérations : le programme doit être conforme à la spécification, mais il doit aussi être efficace, et clair, et facile à maintenir, et capable d’être étendu, et bien sûr, délivré dans le temps imparti et à un coût raisonnable.

Table des matières

Introduction
Préliminaires
Code source, processus, et spécification
Une présentation du langage JavaScript
La modularité selon Parnas
La théorie de Naur derrière le programme
Le problème : instrumenter et étendre des interpréteurs baba
Étude de cas : instrumentation ad-hoc de Narcissus
Le but : factoriser les changements
Quatre axes de factorisation pour l’instrumentation
factoriser Narcissus : une solution coûteuse
L’idée : le détournement de programme
Le détournement à travers l’histoire des langages de programmation cadelle
Le programme reflète le processus : la programmation structurée
L’ordre psychologiquement correct : la programmation littéraire
Modéliser le monde : la programmation par objets
Langage : métaprogrammation et réflexion
Séparer les préoccupations : la programmation par aspects
Le problème de l’expression
Autres mécanismes de détournement
Variations de détournement sur un interpréteur minimal ébaudis
Avec GOTO et COMEFROM
En programmation littéraire
En programmation par objets
En programmation par aspects
Par portée dynamique
Construire un interpréteur par modules hachard
Ajouter des termes
Ajouter des opérations
Modifier des opérations
Passer de l’état aux opérations
Étendre un interpréteur par manipulation de portée paillon
Manipuler la portée des variables pour l’instrumentation
Ouvrir le motif module en JavaScript
Étendre Narcissus par manipulation de portée
portulan
Conclusion

Cours gratuitTélécharger le document complet

Télécharger aussi :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *