Le premier compilateur a été écrit par Grace Hopper en 1952, tandis que l’interprète Lisp a été écrit en 1958 par Steve Russell, élève de John McCarthy. Écrire un compilateur semble être un problème beaucoup plus difficile qu'un interprète. Si tel est le cas, pourquoi le premier compilateur a-t-il été écrit six ans avant le premier interprète?
history
compiler
interpreters
Anguyen
la source
la source
Réponses:
C'est peut-être vrai aujourd'hui, mais je dirais que ce n'était pas le cas il y a 60 ans. Quelques raisons pour lesquelles:
la source
Le point fondamental est que l’environnement matériel informatique des années 50 faisait en sorte que seul un compilateur était réalisable étant donné le traitement des ordinateurs en mode batch.
À l'époque, les meilleures interfaces utilisateur se limitaient principalement aux cartes perforées et aux imprimantes télétypiques . En 1961, le système SAGE est devenu le premier écran à tube cathodique à tube cathodique (CRT) sur ordinateur. La nature interactive d'un interprète n'était donc préférable ni naturelle que beaucoup plus tard.
Dans les années 1950, de nombreux ordinateurs utilisaient des commutateurs sur le panneau avant pour charger des instructions. Les résultats étaient simplement constitués de rangées de lampes / voyants. Les amateurs ont même utilisé des commutateurs et des voyants sur le panneau avant dans les années 1970. Vous connaissez peut-être le fameux Altair 8800 .
D'autres limitations matérielles ont également rendu les interprètes irréalisables. Dans les années 50, la disponibilité de la mémoire principale (par exemple, la mémoire RAM) était extrêmement limitée. Avant le circuit intégré à semi-conducteurs (qui n’est pas venu avant 1958), la mémoire était limitée à une mémoire à noyau magnétique ou à une mémoire de ligne à retard, mesurée en bits ou en mots , sans préfixe. Combinée à la lenteur de la mémoire de stockage secondaire (disque ou bande, par exemple), l'utilisation d'une grande partie de la mémoire pour l'interpréteur constituerait un gaspillage, voire une impossibilité, avant même le chargement du programme en cours d'interprétation.
Les limites de mémoire restaient un facteur important lorsque l’équipe dirigée par John Backus chez IBM créa le compilateur FORTRAN en 1954-1957. Ce compilateur innovant n’a réussi que parce qu’il s’agissait d’un compilateur à optimisation .
La plupart des ordinateurs des années 1950 ne possédaient à peine aucun système d'exploitation, sans parler des fonctionnalités modernes telles que la liaison dynamique et la gestion de la mémoire virtuelle, de sorte que l'idée d'un interprète était trop radicale et peu pratique à cette époque.
Addenda
Les langues des années 1950 étaient primitives. Ils ne comprenaient qu'une petite poignée d'opérations, souvent influencées par les instructions du matériel sous-jacent ou par la définition du problème de leur utilisation cible.
À cette époque, les ordinateurs étaient rarement des ordinateurs à usage général au sens où nous pensons aux ordinateurs aujourd'hui. Qu'ils soient reprogrammables sans avoir à être reconstruits était considéré comme un concept révolutionnaire - auparavant, on utilisait des machines électromécaniques (généralement des calculatrices) pour calculer ou calculer les réponses (la majorité des applications dans les années 1950 étaient de nature numérique).
D'un point de vue informatique, les compilateurs et les interprètes sont à la fois traducteurs et d'une complexité à peu près égale à mettre en œuvre.
la source
Les premiers langages de programmation étaient assez simples (pas de récursivité par exemple) et proches de l'architecture de la machine qui était elle-même simple. La traduction était alors un processus simple .
Un compilateur était plus simple en tant que programme qu'un interprète qui devrait garder ensemble les données pour l'exécution du programme et les tables pour interpréter le code source. Et l'interprète prendrait plus de place , pour lui-même, pour le code source du programme et pour les tables symboliques.
La mémoire pourrait être si rare (pour des raisons de coût et d'architecture) que les compilateurs pourraient être des programmes autonomes écrasant le système d'exploitation (j'en ai utilisé un). Le système d’exploitation a dû être rechargé après la compilation pour pouvoir exécuter le programme compilé. ... ce qui montre clairement que faire fonctionner un interprète pour un vrai travail n'était tout simplement pas une option .
Pour être vrai, la simplicité requise des compilateurs était telle que ceux-ci n'étaient pas très performants (l'optimisation du code en était encore à ses balbutiements, même envisagée). Le code machine écrit à la main avait, au moins jusqu’à la fin des années soixante à certains endroits, la réputation d’être nettement plus efficace que le code généré par le compilateur. Il y avait même un concept de taux d'expansion du code , qui comparait la taille du code compilé au travail d'un très bon programmeur. Il était généralement supérieur à 1 pour la plupart des compilateurs (tous?), Ce qui signifiait des programmes plus lents et, plus important encore, des programmes plus volumineux nécessitant plus de mémoire. C'était toujours un problème dans les années soixante.
L'intérêt du compilateur était la facilité de programmation, en particulier pour les utilisateurs qui n'étaient pas des spécialistes de l'informatique, tels que des scientifiques de divers domaines. Cet intérêt n'était pas la performance du code. Mais encore, le temps de programmation était alors considéré comme une ressource peu coûteuse. Le coût était en temps d’ordinateur, jusqu’en 1975-1980, lorsque le coût passa du matériel au logiciel. Ce qui signifie que même les compilateurs n'ont pas été pris au sérieux par certains professionnels .
Le coût très élevé du temps d’ordinateur constituait un motif supplémentaire de disqualification des interprètes , au point que cette idée aurait été risible pour la plupart des gens.
Le cas de Lisp est très spécial, car c’était un langage extrêmement simple qui le rendait faisable (et l’ordinateur était devenu un peu plus grand en 58). Plus important encore, l’interprète Lisp était une preuve de concept concernant la possibilité de définir la lisp ( méta-circularité ) de Lisp , indépendamment de tout problème d’utilisabilité.
Le succès de Lisp est dû en grande partie au fait que cette auto-définition en a fait un excellent banc d’essai pour l’étude des structures de programmation et la conception de nouveaux langages (ainsi que pour sa commodité pour le calcul symbolique).
la source
Je ne suis pas d'accord avec la prémisse de la question.
Le premier compilateur de l'amiral Hopper (le A-0) ressemblait davantage à un éditeur de liens ou à un langage de macro. Elle stockait les sous-routines sur une bande (chacune étant affectée d'un numéro) et ses programmes étaient écrits sous la forme d'une liste de sous-routines et d'arguments. Le compilateur copiera les sous-routines demandées à partir d'une bande et les réordonnera dans un programme complet.
Elle a utilisé le mot "compiler" dans le même sens que l'on compile une anthologie de poèmes: rassembler divers articles en un seul volume.
Autant que je sache, ce premier compilateur ne possédait ni lexer ni un analyseur syntaxique, ce qui en fait un lointain ancêtre d'un compilateur moderne. Elle créa plus tard un autre compilateur (le B-0, alias FLOW-MATIC) dans le but d’une syntaxe plus proche de l’anglais, mais celle-ci ne fut achevée qu’en 1958 ou 1959 - à peu près au même moment que l’interprète Lisp.
Par conséquent, je pense que la question elle-même est un peu erronée. Il semble que les compilateurs et les interprètes ont co-évolué presque exactement au même moment, sans doute en raison du partage d’idées qui aurait incité de nombreux scientifiques à penser dans le même sens à cette époque.
Une meilleure réponse avec des citations ici: https://stackoverflow.com/a/7719098/122763 .
la source
L'autre partie de l'équation est que les compilateurs étaient une étape abstraite au-dessus d'un assembleur. Nous avons d'abord eu un code machine codé en dur. "Nous" étions l'assembleur. Chaque saut et décalage, etc. a été calculé manuellement en hex (ou octal), puis perforé dans du papier ou des cartes. Ainsi, lorsque des assembleurs sont arrivés sur les lieux, cela nous a permis de gagner énormément de temps. L'étape suivante était les assembleurs de macros. Cela donnait la possibilité d'écrire une macro qui se développerait dans un ensemble d'instructions machine. Fortran et Cobol ont donc constitué un énorme pas en avant. Le manque de ressources (cycles de stockage, de mémoire et de processeur) a obligé les interprètes à usage général à attendre que la technologie se développe. La plupart des premiers interprètes étaient des moteurs à code octet (comme Java ou CLR d’aujourd’hui, mais avec beaucoup moins de fonctionnalités). UCSD Pascal était un langage très populaire (et rapide). MS Basic était un moteur de code octet sous le capot.
En termes de temps d’instruction, tout dépendait du processeur utilisé. L’industrie a connu une grande agitation entre RISC et CISC pendant un certain temps. J'ai personnellement écrit assembleur pour IBM, Data General, Motorola, Intel (quand ils sont arrivés), TI et plusieurs autres. Il y avait une différence assez significative dans les jeux d'instructions, les registres, etc. qui influencerait ce qui était nécessaire pour "interpréter" un code p.
Comme référence de temps, j'ai commencé à programmer dans la compagnie de téléphone vers 1972.
la source
Si vous ne gardez pas tout en mémoire, le code compilé est beaucoup plus rapide. N'oubliez pas que, à cette époque, les fonctions étaient jointes au code compilé. Si vous ne compilez pas, vous ne savez pas de quelles fonctions vous aurez besoin. Donc, vous appelez des fonctions de ... Oh, pas encore de disque, nous sommes au début de la cinquantaine, mais de cartes! En runtime!
Bien sûr, il est possible de trouver des solutions de contournement, mais elles n’ont pas encore été trouvées, car les langues étaient très simples et pas si éloignées du code machine. Et compiler était facile et suffisant.
la source
Avant que le premier compilateur ne soit écrit, les gens écrivaient du code assembleur, ce qui représentait un énorme progrès par rapport au code binaire. À l'époque, il y avait un fort argument que le code compilé par un compilateur serait moins efficace que le code assembleur - à cette époque, la relation entre (coût de l'ordinateur) et (coût du programmeur) était très différente de celle d'aujourd'hui. Il y avait donc une forte résistance contre les compilateurs de ce point de vue.
Mais les compilateurs sont beaucoup plus efficaces que les interprètes. Si vous aviez suggéré d'écrire un interprète à ce moment-là, les gens auraient pensé que vous êtes fou. Pouvez-vous imaginer acheter un ordinateur valant un million de dollars et ensuite gaspiller 90% de son pouvoir d’interprétation du code?
la source
Avant qu'un programme en boucle puisse être interprété, il doit être stocké sur un support pouvant être lu à plusieurs reprises. Dans la plupart des cas, le seul support approprié serait la RAM. Étant donné que le code est généralement saisi sur des cartes perforées qui - pour les langages lisibles par l'homme - risquent d'être en grande partie vides, un traitement quelconque doit être effectué sur le code avant qu'il ne soit stocké dans la RAM. Dans de nombreux cas, le traitement du texte de la carte perforée sous une forme qui convient à une exécution directe par le processeur n’est pas vraiment plus difficile que de le traiter sous une forme qui pourrait être gérée efficacement par un interprète.
Notez que l'objectif des premiers compilateurs n'était pas de produire un fichier de code objet ou en langage assembleur sur un disque, mais plutôt de finir un code dans une RAM prête à être exécutée. Ceci est en fait étonnamment facile quand aucun système d’exploitation n’interfère. Un compilateur peut générer du code commençant à une extrémité de la mémoire et allouer des variables et des cibles de branche commençant à l'autre. Si une instruction est marquée avec le libellé "1234", le compilateur stockera dans la variable appelée "1234" une instruction permettant de passer à l'adresse de génération de code actuelle, en créant cette variable si elle n'existe pas. Une instruction "goto 1234" créera une variable "1234" si elle n'existe pas, puis passera à cette variable [qui, espérons-le, aura un saut vers l'emplacement approprié qui y est stocké avant que cette instruction ne soit exécutée].
goto
une étiquette qui n’a pas encore été définie, car elle sait quand lagoto
compilation va être transformée en variable. Ce n'est peut-être pas le moyen le plus efficace de générer du code, mais il convient à la taille des programmes que les ordinateurs devaient gérer.la source
Parce que les interprètes ont besoin de compilateurs pour fonctionner.
La déclaration ci-dessus n'est pas vraiment vraie. À proprement parler, vous pouvez créer un interprète sans jamais utiliser ou interagir avec un compilateur. Mais les résultats obtenus ne ressembleraient pas beaucoup à ce que vous entendez par ces termes.
Au sens strict, les compilateurs et interprètes font des choses complètement différentes. Un compilateur lit le texte d'une source et le transforme en un autre format: langage d'assemblage, code machine, autre langage de haut niveau, structure de données ou autre. Un interprète, quant à lui, récupère une structure de données et exécute des instructions en fonction de celle-ci.
Ce que nous avons tendance à considérer comme un "compilateur" de nos jours est en fait un compilateur qui a été couplé à un générateur de code : un programme qui récupère les données d'une source et génère du code dans un format basé sur ce qu'il voit. C'est une utilisation assez intuitive des compilateurs, et ce fut l'une des premières choses pour lesquelles les compilateurs ont été créés. Mais si vous le regardez autrement, cela semble très similaire à ce que fait un interprète. Il génère toujours du code au lieu d’effectuer des opérations plus générales, mais le principe est le même.
Si nous examinons la question de l’autre côté, un interprète doit obtenir ses données quelque part . Ce ne sont que des données, vous pouvez donc les construire de la même manière que n'importe quel autre type de données. Puisque nous parlons d’interprétation, il semble naturel que vous puissiez construire vos données à partir d’instructions dans un fichier texte. Mais pour faire cela, vous aurez besoin de quelque chose à lire dans le texte et à créer votre structure de données, et c'est un compilateur . Il est relié à l'interprète au lieu d'un générateur de code, mais c'est tout de même un compilateur.
C'est pourquoi les compilateurs ont été écrits en premier. L’idée d’interpréter les structures de données n’était pas nouvelle, même au moment de la conception des compilateurs, mais c’était le "chaînon manquant" qui permettait aux programmeurs de construire ces structures à partir de texte.
la source
Autre facteur: lorsque les premiers compilateurs ont été écrits, le coût du temps machine était bien plus élevé qu'aujourd'hui. Les interprètes utilisent beaucoup plus de temps machine.
la source