Y a-t-il une raison pour laquelle un point-virgule a été choisi comme terminaison de ligne au lieu d'un symbole différent?
Je veux connaître l'historique de cette décision et j'espère que les réponses mèneront à des idées susceptibles d'influencer les décisions futures.
En anglais, le point-virgule est utilisé pour séparer les éléments d'une liste d'instructions, par exemple
Elle a vu trois hommes: Jamie, qui venait de Nouvelle-Zélande; John, le fils du laitier; et George, un homme décharné.
Lors de la programmation, vous séparez un certain nombre d'instructions et l'utilisation d'un point peut être facilement confondue avec un point décimal. L'utilisation du point-virgule fournit une méthode facile à analyser pour séparer les instructions de programme individuelles tout en restant proche de la ponctuation anglaise normale.
Modifier pour ajouter
. Certaines langues exigeaient que chaque instruction soit placée sur une ligne afin que le retour chariot puisse servir de délimiteur d'instruction. D'autres langues permettaient un format plus libre de la mise en page du texte et nécessitaient donc un caractère de délimitation spécifique. Ce caractère a été choisi pour être le point-virgule, probablement en raison de la similitude avec son utilisation dans la langue anglaise (cela doit être une supposition; je n'étais pas là à l'époque) et comme il ne l'a pas fait produire un conflit avec les autres signes de ponctuation et symboles requis à des fins mathématiques ou syntaxiques.
Modifier à nouveau
La nécessité d'un caractère de terminaison remonte aux exigences pour l'analyse du texte de la langue. Les premiers compilateurs ont été écrits en langage assembleur ou, dans certains cas, directement dans des instructions de machine binaire fabriquées à la main. Le fait d'avoir un caractère spécial qui identifie la fin de l'instruction et délimite le bloc de texte en cours de traitement facilite le traitement. Comme je l'ai dit ci-dessus, d'autres langues ont utilisé le retour chariot ou les crochets. Les familles ALGOL, Pascal, Ada, BCPL, B, C, PL/M et d'autres langages utilisent le point-virgule. Quant à savoir lequel était le premier à utiliser ce personnage particulier, je ne remonte pas assez loin dans l'histoire pour m'en souvenir. Son choix et son adoption sont parfaitement
Pour terminer, je pense qu'il y a eu plus de temps passé sur ces réponses et commentaires que sur la décision d'utiliser le point-virgule pour terminer une déclaration lors de la conception de la première langue qui l'utilisait de cette manière.
De nombreux langages utilisent une syntaxe modélisée d'après C (qui a été modélisée d'après B - merci @Crollster). Comme on peut le voir dans les commentaires, il existe une longue chaîne de ces langages ... B a été inspiré par PL/I, qui a été précédé par ALGOL à utiliser le ;
comme séparateur.
Étant donné qu'en C le terminateur d'instruction est ;
, ces langues emboîtent le pas.
Quant à savoir pourquoi il a été sélectionné comme terminateur de déclaration en C - peut-être en raison de son utilisation en anglais "pour indiquer des déclarations interdépendantes" .
C a également été inventé sur le PDP-11 à une époque où la quantité de mémoire disponible pour les jeux de caractères était limitée, de sorte que les inventeurs des langues ont dû travailler dans ces limites.
FORTRAN a utilisé le retour chariot pour délimiter les instructions. Période utilisée COBOL. LISP n'a rien utilisé, s'appuyant sur des parenthèses pour tout. ALGOL a été la première langue à utiliser le point-virgule pour séparer les instructions. Pascal a suivi l'exemple d'ALGOL, utilisant des points-virgules pour séparer les déclarations.
PL/J'ai utilisé un point-virgule pour terminer les instructions. Il y a une différence, et cela se voit facilement en Pascal. Ada a suivi l'exemple de PL/I sur ce seul article, plutôt que celui d'ALGOL.
Le point-virgule comme séparateur ou terminateur d'instructions a été rapidement accepté par la communauté informatique comme une notation utile, et, pour autant que je sache, tous les langages structurés par blocs suivants ont suivi l'exemple d'ALGOL et ont utilisé un point-virgule pour séparer ou terminer les instructions.
On m'a dit il y a de nombreuses années que BCPL utilisait les deux points-virgules ET retour chariot comme séparateurs/terminateurs d'instructions, mais je n'ai jamais utilisé le langage moi-même et je ne peux pas le vérifier . À un moment donné, l'utilisation du retour chariot pour séparer ou terminer les instructions a été supprimée des descendants de BCPL. BCPL a engendré B, B a engendré C, C a engendré C++, Java, D et toute une foule de choses considérablement moins bien pensées que Pascal et Ada.
Pourquoi pas un autre symbole?
Quelques langues ont utilisé d'autres symboles - les anciennes versions de BASIC utilisaient à la place un signe deux-points, par exemple.
Cependant, en ignorant les quelques exceptions, je pense qu'il y a deux raisons principales. La première est que vous recherchez simplement quelque chose d'ambigu. Dans un analyseur type, si vous rencontrez une erreur suffisamment grave pour que vous ne puissiez pas continuer d'analyser l'instruction en cours, vous essayez normalement de récupérer l'analyseur en synchronisation en sautant simplement au terminateur de l'instruction et en redémarrant l'analyseur à partir de la début de la déclaration suivante. Pour cela, vous voulez quelque chose qui ne se produira normalement nulle part ailleurs dans le code, et un point-virgule se trouve être un symbole avec peu d'autre signification attachée, il est donc assez facile de le dédier à cette fin.
La deuxième raison est quelque peu similaire, mais vise davantage les personnes qui lisent/utilisent le code. Encore une fois, cela revient au fait que le symbole réel que vous utilisez n'a pas beaucoup d'importance. Il y a un avantage substantiel en termes de lisibilité à gagner en utilisant le symbole que votre lecteur est habitué à voir dans un but particulier, quand et si possible. Cela ne signifie pas que C est la seule syntaxe parfaite et tout le reste devrait la suivre servilement, mais cela signifie que suffisamment de gens connaissent ce style de syntaxe qu'un langage vaguement similaire gagne beaucoup (et perd très peu) en suivant à peu près la même syntaxe que possible.
Je note que cela ressemble beaucoup à la conception de presque tous les autres programmes. Si j'écris un programme qui utilise des fenêtres de quelque sorte, j'essaierai simplement d'utiliser les fonctionnalités natives des plateformes cibles. Beaucoup de décisions qui incarnent seront en grande partie arbitraires et pourraient être faites différemment sans perte de fonctionnalité majeure - mais également, les modifier sans une fonctionnalité substantielle gain confond simplement les utilisateurs sans rien accomplir d'utile. Les mêmes principes de base s'appliquent à "qu'est-ce qui doit terminer (ou séparer) des déclarations dans une langue?" comme "à quoi devrait ressembler une barre de défilement", ou "comment devrait fonctionner un contrôle d'arborescence?" Dans tous ces cas, la décision est le plus souvent arbitraire et l'uniformité offre un avantage substantiel en soi.
J'ajouterais que la même chose se produit dans de nombreuses langues, juste d'une manière à laquelle la plupart d'entre nous sont si habitués avant de programmer que peu de gens y pensent. Pourquoi tout le monde utilise-t-il "+" pour indiquer l'addition ou "-" pour indiquer la soustraction? Parce que la forme du symbole n'a pas beaucoup d'importance, mais tous ceux qui acceptent d'appliquer la même signification à chaque symbole comptent beaucoup.
Le point-virgule a été initialement proposé dans ALGOL 60 comme une déclaration séparateur, pas un terminateur.
Avant ALGOL 60, le seul langage de programmation de haut niveau existant était Fortran, qui exigeait que chaque instruction soit sur une ligne distincte. Les déclarations s'étendant sur plusieurs lignes, comme les boucles do, étaient considérées comme une bizarrerie, et elles étaient considérées comme des "blocs d'instructions".
Les concepteurs d'ALGOL 60 ont réalisé que les instructions avaient besoin d'une structure hiérarchique (if-then-else, do-loops, instructions case, etc.) et qu'elles pouvaient être imbriquées les unes dans les autres. Donc, l'idée de chaque déclaration sur une ligne distincte n'avait plus de sens. Composition séquentielle des déclarations de la forme S1; S2; ...; Sn éventuellement entouré de début - fin crochets ont été appelés instructions composées, et s'inscrivent dans la structure hiérarchique des instructions envisagées par ALGOL 60. Donc, ici, le point-virgule est clairement une instruction séparateur, pas un terminateur.
Cela a donné lieu à des problèmes dans la pratique. ALGOL 60 avait également une "déclaration vide" qui était indiquée par l'écriture de rien. Donc, on pourrait écrire " begin S1; end " où le point-virgule apparaît comme s'il terminait S1. Mais le compilateur ALGOL 60 l'a vraiment traité comme un séparateur entre S1 et une instruction vide invisible qui le suit. Ces subtilités étaient un peu trop pour les programmeurs pratiques. Ayant été habitués à des langages orientés ligne comme Assembly et Fortran, ils pensaient vraiment au point-virgule comme terminateur pour les instructions. Lorsque les programmes étaient écrits, le point-virgule était généralement placé à la fin des instructions, comme ceci:
a [i]: = 0; i: = i + 1
et le point-virgule ressemblait vraiment à un terminateur pour la première instruction. Si les programmeurs traitaient le point-virgule comme un terminateur, une instruction comme celle-ci donnerait une erreur de syntaxe:
si i> 0 alors a [i]: = 0; sinon a [i]: = 1;
parce que le point-virgule termine le "si" et, donc, le "else" se balance. Les programmeurs étaient profondément confus.
Ainsi, PL/I, qui a succédé à IBM pour Fortran orienté ligne, a décidé de faire du point-virgule une instruction terminator plutôt qu'un séparateur. Les programmeurs étaient satisfaits de ce choix. La majorité des langages de programmation ont emboîté le pas. (Pascal a résisté à la tendance, mais son successeur Ada y a renoncé.)
[Note ajoutée: article Wikipedia sur les comparaisons de langage de programmation a un joli tableau résumant comment le point-virgule est traité dans divers langages de programmation.]
C'est un travail de supposition à peu près pur, mais en regardant un clavier standard QWERTY limité à ASCII les caractères naturels pour la terminaison/séparation seraient.!?, :; et les retours chariot. de ceux-ci!?: devraient être immédiatement disqualifiés pour avoir pris plusieurs clés et la terminaison de la déclaration va être une chose très courante. être un terminateur étant donné l'espace limité des ordinateurs initiaux. les retours de chariot seraient disqualifiés après que les lignes de code auraient pu être plus longues que ce qui peut être affiché sur une seule ligne à l'écran, donc il serait plus difficile de lire un programme lorsque les lignes devait être défilé horizontalement, ou nécessiter des caractères supplémentaires pour créer une continuation sur la ligne suivante, ce qui ajoute encore de la complexité. cela laisse, et; comme options, de celles-ci, est utilisé beaucoup plus souvent par écrit par rapport à; donc le point-virgule est choisi b parce que c'est le plus facile à taper, moins déroutant parce qu'il ajoute du sens à un caractère avec un sens limité et moins compliqué parce que des cas spéciaux n'existent pas vraiment avec son utilisation.
Le point-virgule a été choisi parce que c'était le meilleur personnage basé sur la paresse et la simplicité.
C'est en grande partie un choix arbitraire. Certaines langues ont fait d'autres choix. COBOL termine les instructions avec le .
personnage. FORTRAN, BASIC et Python terminent généralement les instructions par des sauts de ligne (avec une syntaxe spéciale pour les instructions multilignes). Et LISP place ses instructions entre parenthèses.
La raison principale ;
est si populaire qu'un séparateur/terminateur d'instructions est que la plupart des langages populaires d'aujourd'hui sont basés sur ALGOL , qui a utilisé cette convention.
au lieu d'un symbole différent?
Quel autre symbole pourriez-vous choisir?
Les caractères ASCII # $ @ [] ^ _ `{|} ~ n'étaient pas toujours présents dans les premiers encodages de caractères comme ISO 646 .
Les personnages ()*+-/<=>
sont généralement utilisés comme opérateurs mathématiques et créent des ambiguïtés d'analyse s'ils sont utilisés comme terminateurs d'instructions.
product = a * b * // If '*' were a statement terminator,
c * d * // Are there two factors, or four?
Des problèmes similaires s'appliqueraient à '
et "
, qui sont généralement utilisés comme délimiteurs de chaîne; ,
, qui est généralement utilisé pour séparer les arguments de fonction, et .
, qui est généralement utilisé comme point décimal (ou comme délimiteur dans des constructions comme some_struct.some_field
).
Cela laisse !%&:;?
.
Choisir !
ou ?
ne causerait probablement pas de difficultés techniques, mais leur signification en anglais donnerait une mauvaise humeur au programme.
print(x)? # Yes, you should.
# It's an IMPERATIVE language; stop questioning my commands.
print(x)! # OK! You don't have to shout!
Le &
serait un choix plus judicieux comme séparateur d'instructions (et non comme terminateur), car
do_thing_a() &
do_thing_b()
peut être lu comme une commande pour faire la chose A et puis faire la chose B. Mais la plupart des langues avec un &
L'opérateur l'utilise comme logique ou bit à bit ET à la place.
Le %
le signe peut prêter à confusion dans des instructions comme interest_rate = 2.99%
(ce qui définirait la variable sur 2.99
au lieu de la valeur attendue 0.0299
). Bien sûr, la signification mathématique bien connue de %
n'a pas empêché C de l'utiliser comme opérateur restant.
Alors ça laisse :
et ;
.
:
est un choix judicieux, et est en effet utilisé comme séparateur d'instructions intra-ligne dans la plupart des dialectes de BASIC.
Mais ;
a la grammaire anglaise de son côté; il peut être utilisé pour séparer les clauses d'une phrase.
Plutôt que d'essayer de répondre à votre question principale, je pense qu'il vaut mieux se concentrer sur votre question implicite:
Je veux connaître l'historique de cette décision, et j'espère que les réponses mèneront à des informations susceptibles d'influencer les décisions futures dans la conception et la mise en œuvre des langages de programmation.
Si vous souhaitez en savoir plus sur la conception du langage de programmation et l'historique d'implémentation, et obtenir plus d'informations sur le processus, alors les procédures des History of Programming Language Conferences sont un très bon point de départ. (Je pense cependant que vous aurez besoin d'un abonnement ACM pour pouvoir accéder aux débats.)
Pourquoi les instructions de nombreux langages de programmation se terminent-elles par des points-virgules? Y a-t-il une raison pour laquelle un point-virgule a été choisi comme terminaison de ligne au lieu d'un symbole différent?
En prenant votre question principale comme un exemple de question à laquelle vous voudrez peut-être essayer de répondre en lisant les procédures HOPL, j'aimerais offrir le point suivant: les personnes qui conçoivent un nouveau langage de programmation le font généralement parce qu'elles considèrent celles qu'elles savent être cassé/déficient en quelque sorte. Leur nouveau langage est, d'une part, conçu pour corriger cette lacune. D'un autre côté, les concepteurs de langage copieront également des éléments de conception d'autres langues qu'ils jugent bons, ou ils ne changent tout simplement pas les éléments avec lesquels ils n'ont pas rencontré de problème.
Surtout que la dernière partie est importante: au lieu d'essayer de savoir quel langage de programmation a jamais été le premier à utiliser des points-virgules comme terminateurs et pourquoi de nombreux autres langages de programmation ont copié cela, vous en apprendrez probablement plus en regardant les langages qui l'ont fait pas copiez-le. Par exemple, alors que Smalltalk s'est beaucoup inspiré de Simula, il n'a pas copié sa syntaxe et en particulier son utilisation des points-virgules comme terminateurs d'instruction. Il a changé les terminateurs (séparateurs vraiment) en un point final et utilise le point-virgule pour autre chose. Inversement, la première langue qui a jamais utilisé un point-virgule comme terminateur d'instruction peut avoir eu une raison de changer cela par rapport à ce qui était utilisé dans les langues qui l'ont précédé. Il est également possible que ce soit la première langue à introduire le concept de terminateur d'instruction (ou l'a fait indépendamment des autres langues) et que le point-virgule ait été utilisé pour une raison qui est maintenant perdue. (Je soupçonne que ce dernier est le cas ici, car aucun des autres répondants n'a pu trouver une citation de la personne qui a introduit le point-virgule plutôt que de proposer des suppositions a posteriori sur la raison pour laquelle le point-virgule était un bon choix.) Mais pour reformuler mon Je pense que vous en apprendrez plus en regardant pourquoi les concepteurs de langage ont changé les choses plutôt que pourquoi ils les ont copiées/conservées. Lorsque les gens changent des choses, ils veulent ou doivent généralement expliquer le changement, alors qu'ils ne le font pas en copiant ou en gardant les mêmes choses parce que "pourquoi changerions-nous? c'est comme ça que ça se passe! "
Il s'agit de visibilité.
Les premiers séparateurs de déclaration étaient le ". comme en COBOL et nouvelle ligne, retour chariot en FORTRAN.
Le CR s'est révélé limitatif dans la mesure où il est difficile de faire circuler une déclaration sur plusieurs lignes.
L'arrêt complet a causé un problème plus intéressant. Lorsque vous lisez du texte en anglais, votre cerveau traite les arrêts complets au niveau subliminal, vous êtes conscient qu'une phrase est terminée et vous pouvez vous arrêter pour respirer, mais vous ne le remarquez pas vraiment. cela l'a signalé. Également dans de nombreuses polices, le '.' est le plus petit caractère possible parfois rendu sous la forme d'un seul pixel. Les périodes manquantes ou supplémentaires sont devenues la cause d'erreur la plus courante dans les programmes COBOL.
Donc, en apprenant des premières erreurs, ALGOL a choisi un terminateur spécifique qui permettrait à une déclaration de circuler sur plusieurs lignes et en a choisi un qui était visible et facilement remarqué par les lecteurs humains. Le point-virgule étant à la fois assez grand et assez inhabituel en anglais courant pour ne pas être traité inconsciemment.
J'ai cru comprendre qu'il avait été choisi parce qu'il fallait un terminateur de déclaration explicite autre qu'un retour chariot/nouvelle ligne. À l'époque des écrans à 80 colonnes, le fait d'avoir une seule ligne de code sur plusieurs lignes était suffisamment courant pour que l'utilisation de\r ou\n pour le terminateur d'instruction ne fonctionne pas.
Les points-virgules étaient simplement pratiques car ils ne sont pas utilisés dans les instructions logiques/mathématiques. En tant que tels, ils n'entrent pas en conflit avec le contenu réel des déclarations dans une mesure significative.
Personnellement, je pense que l'utilisation continue du point-virgule, ainsi que les exigences de style pour garder les lignes sous 80 caractères, sont franchement stupides et anachroniques. Des langages tels que python ont largement démontré que vous pouvez écrire du code facile à comprendre et concis plus facilement sans eux. De plus, si vous avez des problèmes avec des lignes plus longues que 80 caractères, vous avez besoin d'un moniteur plus grand .
Voici deux questions: pourquoi ALGOL a obtenu le point-virgule et pourquoi d'autres langues l'ont recherché.
La première question a déjà reçu de nombreuses réponses ici.
En tant que deuxième, l'ALGOL a été très largement utilisé comme langage pseudocode pour l'écriture d'algorithmes. Ainsi, les points-virgules sont rapidement devenus naturels pour les utilisateurs de différentes langues. Et naturellement, ils ont été pris pour les langues plus jeunes.
Je peux me tromper, mais je pense que cela a quelque chose à voir avec le fait que dans de nombreux assembleurs, un point-virgule a été utilisé pour commencer un commentaire, généralement mis après une instruction. Tout après un ;
était un commentaire et ne faisait plus partie de l'instruction elle-même.
Ensuite, il est nécessaire de mettre fin aux instructions lorsque vous les tapez dans un interpréteur. Des instructions courtes (par exemple des expressions mathématiques) peuvent être terminées en appuyant simplement sur la touche Entrée, indiquant à l'interprète que l'expression est prête à être calculée et qu'elle a produit un résultat. Mais parfois, on voulait entrer plusieurs lignes de code pour l'instruction, donc une façon d'y parvenir était d'utiliser un caractère spécial comme terminateur de l'instruction au lieu de dépendre uniquement de la touche Entrée. De cette façon, l'utilisateur pouvait entrer plus de lignes de code à la fois, car Enter ne l'avait pas encore envoyé à l'interpréteur. Ce n'est que lorsque l'interpréteur a trouvé le caractère de fin dans une ligne entrée avec Entrée, qu'il l'exécutait enfin et calculait son résultat.
Maintenant, combinez ces deux choses ensemble, et le point-virgule semble être un choix évident pour le caractère de fin: il indique où se termine la partie instruction et la partie commentaire, donc quand l'interprète le rencontre en ligne, il sait qu'il peut vider toutes les lignes de l'expression qu'elle a tamponné jusqu'à présent et l'exécutent, car l'instruction vient de se terminer, maintenant nous sommes dans un commentaire (enfin, au moins jusqu'à la fin de cette ligne, car la ligne suivante commencera dans le code mode, en commençant une nouvelle expression/instruction).
Cela suppose, bien sûr, que c'est vraiment le point-virgule qui a été utilisé pour les commentaires par la personne qui a eu l'idée de le réutiliser comme terminateur d'instruction. Ayant été un autre caractère, nous aurions pu nous retrouver avec un terminateur d'instruction différent.
Inb4: Non, ce n'est pas un compte historique. Je n'ai aucune preuve que c'est ainsi que les points-virgules ont pris vie. C'est juste comme ça que j'imagine que cela aurait pu arriver.