Points-virgules facultatifs

10

Le plus souvent, dans un langage impératif à usage général - les points-virgules comme délimiteurs d'instructions sont soit requis, soit totalement interdits (par exemple C et Python).

Cependant, certaines langues, comme JavaScript, vous permettent de désactiver la délimitation de vos déclarations avec des points-virgules, au profit d'autres délimiteurs (comme une nouvelle ligne).

Quelles sont les décisions de conception derrière cela? Je comprends que les points-virgules sont essentiels lors de l'écriture de plusieurs instructions sur la même ligne, mais y a-t-il une autre raison pour les rendre obligatoires (sauf en suivant C)?

Aber Kled
la source
1
Vous devez penser aux terminateurs d'instructions (perl, c) et aux délimiteurs d'instructions (javascript, pascal).
5
En Python, les points-virgules peuvent être utilisés pour séparer plusieurs instructions sur la même ligne. Et comme une instruction "vide" est autorisée, des points-virgules peuvent être utilisés à la fin de la plupart des instructions.
Greg Hewgill
1
I understand that semicolons are essential when writing multiple statements on the same line- Dépend de la langue. Mon favori n'a pas de délimiteurs de ce type, l'instruction suivante commence lorsque tous les arguments de fonction ont été utilisés.
Izkata
1
@MichaelT: Je ne pense pas que vos classifications soient correctes: Perl appartient sans doute aux deux groupes, et JavaScript est en fait dans le camp des "terminateurs d'instructions" (car les implémentations sont nécessaires pour déduire un point-virgule avant }ou à la fin du fichier).
ruakh
Oui, cela dépend absolument de la langue. Ma conjecture personnelle serait que les points-virgules ne sont qu'une sorte de convention commune, que la plupart des concepteurs de langage suivent. Au moins, cela a du sens d'un point de vue plus naturel. Même chose avec {et} pour les blocs, soit dit en passant: ils sont utilisés par de nombreuses langues, mais pas tous et vous n'avez pas à le faire. Il n'y a aucune raison universelle derrière cela.
JensG

Réponses:

24

Les rendre obligatoires (ou les interdire complètement) réduit le nombre de cas d'angle, élimine une source potentielle de bogues obscurs et simplifie la conception du compilateur / interprète.

Les concepteurs de langage qui ont choisi de les rendre facultatifs ont choisi de vivre avec l'ambiguïté en échange d'une plus grande flexibilité syntaxique.

Robert Harvey
la source
7
@RobertHarvey Heretic! Il devrait y avoir une façon évidente de le faire et une seule. Soit dit en passant, il n'y a qu'une seule façon de le faire en perl.
1
BTW - certaines langues ont une bonne quantité de redondance dans les grammaires en général, donc rendre le point-virgule facultatif n'est que parfois ambigu dans la pratique. Cela dit, je pense que le point-virgule est le mauvais bit de redondance à supprimer - j'aime bien Haskell où vous supprimez les parens et les virgules pour les arguments à la place. OK, vous pouvez aussi supprimer le point-virgule dans Haskell, mais ce n'est pas vraiment la même chose que Javascript.
Steve314
2
IIRC le problème est qu'ils ne correspondent pas au modèle formel mais que les générateurs d'analyseurs ne produisent pas de bons messages d'erreur. C'est-à-dire qu'ils ont une connaissance limitée des erreurs courantes tandis que l'analyseur manuscrit peut obtenir un message d'erreur beaucoup plus utile. Gcc, par exemple, utilisait le bison pour la grammaire C. De même, le problème est que les «cas de bord» ne sont pas des cas de bord formels mais des cas mous - c'est-à-dire que pour l'analyseur, l'AST est clair et pour l'homme, l'AST «est clair», mais ils ne sont pas d'accord sur ce à quoi ressemble l'AST.
Maciej Piechotka
2
@Maciej Piechotka - Je ne voulais pas laisser entendre que les parens étaient facultatifs dans Haskell. Je parle de supprimer quelque chose de redondant comme décision de conception de langage. Le fait est que vous n'utilisez pas de parens ou de virgules pour un appel de fonction dans Haskell. Vous pouvez passer un tuple comme argument, mais c'est toujours la syntaxe pour un tuple, pas pour passer des arguments. Haskell (et ML et autres) "a supprimé" les parenthèses et les virgules pour les arguments de fonction dans le sens où il existe cette convention commune dans d'autres langues (depuis Algol?), Mais Haskell ne fait pas cela.
Steve314
1
@Maciej Piechotka - Bien sûr, cela n'a jamais été vraiment une convention universelle de toute façon - ce n'est pas parce que les langues de la famille algol le font que d'autres langues se définissent par rapport à cela, donc ma déclaration "abandonnée" est fausse dans ce sens - mais avec tout les langues de la famille C ces jours-ci, c'est un peu comme ça.
Steve314
15

JavaScript nous a montré que c'est une très mauvaise idée. Par exemple:

return
0;

En C, cela renvoie une valeur de 0. En JavaScript, cela revient undefinedcar un point-virgule est inséré après l'instruction de retour, et il n'est pas immédiatement évident pourquoi votre code se casse, sauf si vous connaissez les détails de l'insertion automatique du point-virgule.

Mason Wheeler
la source
1
@delnan: Python n'est pas conçu pour ressembler à C. Il est bien connu qu'il est basé sur l'indentation et donc très orienté sur les lignes, et il ne nécessite pas de points-virgules. JavaScript technique ne les oblige; il en insère un lorsqu'il en trouve un manquant, ce qui transforme ce qui ressemble à une instruction syntaxiquement valide en deux instructions distinctes avec une sémantique complètement différente.
Mason Wheeler
7
Ce n'est pas une mauvaise idée, c'est juste déroutant pour les personnes qui essaient d'utiliser JavaScript sans se soucier d'en savoir plus sur son insertion automatique de point-virgule . Peut-être au lieu de dire "c'est une très mauvaise idée", vous pourriez dire plus précisément "rendre les points-virgules facultatifs introduit des pièges pour les programmeurs qui ne sortent pas et n'apprennent pas tous les détails".
TehShrike
4
@delnan: La raison pour laquelle il est surprenant est que JavaScript n'insère généralement pas de point-virgule à la fin d'une ligne, sauf pour corriger un programme par ailleurs invalide. After returnest l'un des rares cas où JavaScript insérera un point-virgule même si le programme serait valide sans lui. (Mais bien sûr, cela sape le point de Mason Wheeler. Le problème n'est pas que les points-virgules sont facultatifs, c'est que les règles ne sont pas cohérentes.)
ruakh
6
@TehShrike: Rendre les points-virgules facultatifs introduit des pièges pour tous les programmeurs, car il interprète arbitrairement les fautes de frappe au lieu de vous demander ce que vous vouliez dire. Tout le monde fait une faute de frappe de temps en temps.
Jan Hudec du
1
javascript a montré que son implémentation de points-virgules facultatifs est défectueuse. Cela ne montre pas que les points-virgules facultatifs sont mauvais en soi.
CodesInChaos
4

Il simplifie quelque peu votre grammaire et votre analyseur pour rendre les points-virgules obligatoires. Essentiellement, cela permet au lexer de vider tous les espaces, y compris les nouvelles lignes, et l'analyseur n'a pas à s'en soucier du tout.

D'un autre côté, une fois que vous commencez à vouloir parler à l'analyseur des espaces blancs, ce n'est pas si difficile de rendre les points-virgules facultatifs. Vous pouvez souvent les regrouper avec un whitespacejeton et votre analyseur peut très bien le gérer.

Par exemple, essayez d'insérer les points-virgules dans la série d'instructions C suivante.

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

Bien qu'il y ait des choses étranges que vous ne pouvez plus faire, comme while(1);, pour la plupart, il est relativement facile avec les techniques d'analyse modernes de déterminer où se terminent les instructions sans délimiteur spécifique. Même si vous voulez toujours autoriser les trucs bizarres, ce n'est pas si difficile de faire un newline_or_semicolonnon-terminal.

Karl Bielefeldt
la source
Lorsque C a été initialement développé au début des années 1970, des terminateurs d'instructions étaient nécessaires pour simplifier les compilateurs. Au milieu des années 90, lorsque Javascript a été développé, c'était moins une préoccupation.
Sean McSomething
3

Les points-virgules sont utiles dans une grammaire pour 2 raisons. Tout d'abord, il vous permet de diviser de longues instructions en plusieurs lignes sans avoir de personnages de continuation (je parle de vous, Fortran et Basic). Deuxièmement, cela permet à l'analyseur d'avoir un moyen de "renoncer" à l'analyse lorsque la syntaxe est vraiment compliquée à cause d'une faute de frappe. Volant l'exemple de Karl Bielefeldt,

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

imaginez que vous avez tapé un paren ouvert supplémentaire:

functionCall((3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

maintenant où est l'erreur? Si vous aviez les points-virgules, il est plus facile pour l'analyseur d'abandonner au premier point-virgule. Il pourrait même continuer à analyser après le point-virgule s'il le voulait.

functionCall((3, 4);  <- something is wrong here. emit error and keep going.
                      9 + (3 / 8); variable++; while(1) { printf("Hello, world\n"); }

Il est désormais plus facile pour l'analyseur de signaler une erreur et de localiser plus facilement la ligne / colonne où elle s'est produite.

Mark Lakata
la source
1
Fortran et Basic ont au moins décemment choisi des marqueurs de continuation de ligne (& et _, respectivement). Pour pur "" OMG, à quoi pensaient-ils ", rien ne vaut FoxPro. Pour continuer une ligne, vous avez utilisé un point-virgule.
DougM
2

Les points-virgules ne sont pas toujours tout ou rien comme vous le mentionnez dans votre question. Par exemple, la grammaire de Lua est soigneusement conçue pour être de forme libre (tous les espaces, y compris les retours à la ligne, peuvent être ignorés) mais aussi sans avoir besoin d'utiliser de point-virgule. Par exemple, les programmes suivants sont équivalents:

--One statement per line
x = 1
y = 2

--Multiple statements per line
x = 1 y = 2

--You can add semicolons if you want but its just for clarity:
x = 1; y = 2
hugomg
la source
0

Hormis la conception et la construction, je pense que beaucoup de programmeurs viennent d'horizons différents et certains ont appris à utiliser le point-virgule et d'autres non. Un grand nombre de nouvelles langues émergentes ne nécessitent pas de point-virgule mais permettent tout de même d'exister. Je pense que cela pourrait simplement être un moyen d'amener plus de programmeurs à apprendre à coder dans ces nouveaux langages sans avoir à renoncer à leurs habitudes depuis le début.

HeadphoneHaxZ
la source