Optionale Semikolons


10

Meistens sind in einer allgemeinen imperativen Sprache Semikolons als Anweisungsbegrenzer entweder erforderlich oder vollständig unzulässig (z. B. C und Python).

In einigen Sprachen, wie z. B. JavaScript, können Sie jedoch die Begrenzung Ihrer Anweisungen durch Semikolons zugunsten anderer Trennzeichen (z. B. Zeilenumbrüche) deaktivieren.

Welche Designentscheidungen stehen dahinter? Ich verstehe, dass Semikolons wichtig sind, wenn mehrere Anweisungen in dieselbe Zeile geschrieben werden. Gibt es jedoch einen anderen Grund, sie verbindlich zu machen (außer nach C)?


1
Sie müssen über Anweisungsabschlusszeichen (Perl, C) und Anweisungsbegrenzer (Javascript, Pascal) nachdenken.

5
In Python können Semikolons verwendet werden, um mehrere Anweisungen in derselben Zeile zu trennen. Und da eine "leere" Anweisung zulässig ist, können am Ende der meisten Anweisungen Semikolons verwendet werden.
Greg Hewgill

1
I understand that semicolons are essential when writing multiple statements on the same line- Kommt auf die Sprache an. Mein Favorit hat überhaupt keine solchen Begrenzer, die nächste Anweisung beginnt, wenn alle Funktionsargumente aufgebraucht sind.
Izkata

1
@MichaelT: Ich denke nicht, dass Ihre Klassifizierungen korrekt sind: Perl gehört wohl zu beiden Gruppen, und JavaScript befindet sich tatsächlich im Lager "Statement Terminators" (da Implementierungen erforderlich sind, um ein Semikolon vor }oder am Ende der Datei abzuleiten).
Ruakh

Ja, hängt absolut von der Sprache ab. Meine persönliche Vermutung wäre, dass Semikolons nur eine Art allgemein vereinbarte Konvention sind, der die meisten Sprachdesigner folgen. Zumindest macht es unter dem Gesichtspunkt einer natürlicheren Sprache Sinn. Übrigens auch mit {und} für Blöcke: Sie werden von vielen Sprachen verwendet, jedoch nicht von allen, und Sie müssen dies tatsächlich nicht tun. Es gibt keinen universellen Grund dafür.
JensG

Antworten:


24

Wenn Sie sie obligatorisch machen (oder sie vollständig verbieten), wird die Anzahl der Eckfälle verringert, eine potenzielle Quelle für obskure Fehler beseitigt und das Compiler- / Interpreter-Design vereinfacht.

Die Sprachdesigner, die sich dafür entschieden haben, sie optional zu machen, haben sich dafür entschieden, mit der Mehrdeutigkeit zu leben, um eine größere syntaktische Flexibilität zu erreichen.


7
@ RobertHarvey Heretic! Es sollte einen offensichtlichen Weg geben und nur einen. Übrigens gibt es nur einen Weg, dies in Perl zu tun.

1
Übrigens - einige Sprachen weisen im Allgemeinen eine angemessene Redundanz in der Grammatik auf, so dass es in der Praxis nur gelegentlich mehrdeutig ist, das Semikolon optional zu machen. Trotzdem denke ich, dass das Semikolon das falsche Maß an Redundanz ist - ich mag Haskell, bei dem Sie stattdessen die Parens und Kommas für Argumente löschen. OK, Sie können das Semikolon auch in Haskell ablegen, aber es ist nicht wirklich dasselbe wie Javascript.
Steve314

2
IIRC das Problem ist, dass sie nicht zum formalen Modell passen, aber dass die Parser-Generatoren keine guten Fehlermeldungen erzeugen. Das heißt, sie haben nur begrenzte Kenntnisse über häufige Fehler, während handgeschriebene Parser viel nützlichere Fehlermeldungen erhalten können. Gcc verwendet zum Beispiel Bison für die C-Grammatik. In ähnlicher Weise besteht das Problem darin, dass die "Randfälle" keine formalen Randfälle sind, sondern weiche - dh für Parser ist der AST klar und für Menschen ist der AST "klar", aber sie stimmen nicht überein, wie AST ist.
Maciej Piechotka

2
@ Maciej Piechotka - Ich wollte nicht implizieren, dass die Parens in Haskell optional waren. Ich spreche davon, etwas Redundantes als Entscheidung für das Sprachdesign fallen zu lassen. Der Punkt ist, dass Sie für einen Funktionsaufruf in Haskell keine Parens oder Kommas verwenden. Sie können ein Tupel als Argument übergeben, aber das ist immer noch die Syntax für ein Tupel, nicht zum Übergeben von Argumenten. Haskell (und ML und andere) "löschten" die Parens und Kommas für Funktionsargumente in dem Sinne, dass es diese gemeinsame Konvention in anderen Sprachen gibt (seit Algol?), Aber Haskell tut das nicht.
Steve314

1
@Maciej Piechotka - Natürlich war es sowieso nie wirklich eine universelle Konvention - nur weil Sprachen der Algol-Familie dies tun, heißt das nicht, dass sich andere Sprachen relativ dazu definieren, also ist meine "fallengelassene" Behauptung in diesem Sinne falsch - aber mit allen In den Sprachen der C-Familie fühlt es sich heutzutage ein bisschen so an.
Steve314

15

JavaScript hat uns gezeigt, dass dies eine sehr schlechte Idee ist. Zum Beispiel:

return
0;

In C gibt dies den Wert 0 zurück. In JavaScript wird dies zurückgegeben, undefinedweil nach der return-Anweisung ein Semikolon eingefügt wird und es nicht sofort offensichtlich ist, warum Ihr Code beschädigt wird, es sei denn, Sie kennen die Details der automatischen Semikolon-Einfügung.


1
@delnan: Python sieht nicht wie C aus. Es ist bekannt dafür, dass es auf Einrückungen basiert und daher stark zeilenorientiert ist, und es erfordert keine Semikolons. JavaScript technisch tut sie benötigen; Es fügt eine ein, wenn eine fehlende gefunden wird, wodurch eine syntaktisch gültige Anweisung in zwei unterschiedliche Anweisungen mit völlig unterschiedlicher Semantik umgewandelt wird.
Mason Wheeler

7
Es ist keine schlechte Idee, es ist nur , um Menschen zu verwirren , die versuchen , JavaScript zu verwenden , ohne sich um seine lernen automatische Semikolon Einfügen . Anstatt zu sagen, "das ist eine sehr schlechte Idee", könnten Sie genauer sagen, "Semikolons optional zu machen, bringt Fallstricke für Programmierer mit sich, die nicht alle Details lernen".
TheShrike

4
@delnan: Der Grund dafür ist, dass JavaScript normalerweise kein Semikolon am Ende einer Zeile einfügt , außer um ein ansonsten ungültiges Programm zu reparieren. After returnist einer von nur wenigen Fällen, in denen JavaScript ein Semikolon einfügt, selbst wenn das Programm ohne dieses Semikolon gültig wäre. (Aber natürlich untergräbt dies den Standpunkt von Mason Wheeler. Das Problem ist nicht, dass die Semikolons optional sind, sondern dass die Regeln inkonsistent sind.)
Ruakh

6
@TehShrike: Wenn Sie Semikolons optional machen, entstehen Fallstricke für alle Programmierer, da Tippfehler willkürlich interpretiert werden, anstatt Sie zu fragen, was Sie gemeint haben. Jeder macht ab und zu einen Tippfehler.
Jan Hudec

1
Javascript hat gezeigt, dass die Implementierung optionaler Semikolons fehlerhaft ist. Es zeigt nicht, dass optionale Semikolons per se schlecht sind.
CodesInChaos

4

Es vereinfacht Ihre Grammatik und Ihren Parser etwas, sodass die Semikolons obligatorisch sind. Im Wesentlichen ermöglicht es dem Lexer, alle Leerzeichen einschließlich Zeilenumbrüchen zu löschen, und der Parser muss sich überhaupt nicht darum kümmern.

Wenn Sie dem Parser jedoch ohnehin etwas über Leerzeichen erzählen möchten, ist es nicht so schwer, die Semikolons optional zu machen. Sie können sie oft einfach mit einem whitespaceToken zusammenfassen und Ihr Parser kann damit gut umgehen.

Versuchen Sie beispielsweise, die Semikolons in die folgende Reihe von C-Anweisungen einzufügen.

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

Obwohl es einige seltsame Dinge gibt, die Sie nicht mehr tun können, wie while(1);zum Beispiel zum größten Teil, ist es mit modernen Parsing-Techniken relativ einfach zu bestimmen, wo die Anweisungen ohne ein bestimmtes Trennzeichen enden. Selbst wenn Sie immer noch das seltsame Zeug zulassen möchten, ist es nicht so schwer, ein newline_or_semicolonNicht-Terminal zu erstellen.


Als C ursprünglich in den frühen 1970er Jahren entwickelt wurde, wurden Anweisungsabschlusszeichen benötigt, um Compiler zu vereinfachen. Mitte der 90er Jahre, als Javascript entwickelt wurde, war dies weniger besorgniserregend.
Sean McSomething

3

Semikolons sind in einer Grammatik aus zwei Gründen nützlich. Erstens können Sie lange Anweisungen in mehrere Zeilen aufteilen, ohne gottesfürchtige Fortsetzungszeichen zu haben (ich spreche von Ihnen, Fortran und Basic). Zweitens kann der Parser das Parsen "aufgeben", wenn die Syntax aufgrund eines Tippfehlers wirklich verworren ist. Diebstahl von Karl Bielefeldts Beispiel,

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

Stellen Sie sich vor, Sie haben einen zusätzlichen offenen Paren eingegeben:

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

Wo ist nun der Fehler? Wenn Sie die Semikolons hatten, ist es für den Parser einfacher, beim ersten Semikolon aufzugeben. Es könnte sogar nach dem Semikolon weiter analysiert werden, wenn es wollte.

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

Jetzt ist es für den Parser einfacher, einen Fehler zu melden und die Zeile / Spalte, in der er aufgetreten ist, leichter zu finden.


1
Fortran und Basic haben zumindest anständige Linienfortsetzungsmarkierungen (& bzw. _) ausgewählt. Für schiere "" OMG, was dachten sie ", nichts geht über FoxPro. Um eine Zeile fortzusetzen, haben Sie ein Semikolon verwendet.
DougM

2

Semikolons sind nicht immer alles oder nichts, wie Sie es in Ihrer Frage erwähnen. Zum Beispiel Lua Grammatik s‘ist sorgfältig freie Form sein (alle Leerzeichen, einschließlich Zeilenumbrüche kann ignoriert werden) , sondern auch , ohne zu verwenden , um alle Semikolons gestaltet. Die folgenden Programme sind beispielsweise gleichwertig:

--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

0

Abgesehen von Design und Konstruktion glaube ich, dass viele Programmierer aus unterschiedlichen Bereichen stammen und einige gelernt haben, das Semikolon zu verwenden, andere nicht. Viele neuere Sprachen, die auftauchen, benötigen kein Semikolon, lassen es aber dennoch zu. Ich denke, es könnte nur eine Möglichkeit sein, mehr Programmierer dazu zu bringen, das Codieren in diesen neuen Sprachen zu lernen, ohne ihre Gewohnheiten von Anfang an aufgeben zu müssen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.