Warum verschachteln die meisten Programmiersprachen keine Blockkommentare?

18

Ein paar, aber meines Wissens keine der beliebtesten. Hat das Verschachteln von Kommentaren etwas Schlechtes?

Ich plane, Blockkommentare in der (kleinen) Sprache zu platzieren, an der ich arbeite, aber ich würde gerne wissen, ob dies eine schlechte Idee ist.

amara
quelle
Hier ein paar Antworten: ohh, das macht Sinn =) Ich mache dann total verschachtelte Blockkommentare; Obwohl ich eine separate Lexing-Stufe habe, ist dies nicht die beschriebene einschränkende Art der SK-Logik.
@Vuntic: Wenn Sie eine separate Lexing-Phase haben, in der Dinge verwendet werden, die komplizierter sind als reguläre Ausdrücke, können Leistungsprobleme auftreten. REs sind durch die Implementierung von DFAs schnell und einfach zu verwenden.
David Thornley
Es fängt mehr Fehler früher ab, um keine Verschachtelung zuzulassen
4
@ David: ... überhaupt nicht. Es ist eigentlich sehr schnell.
Amara
Ich würde vorschlagen, wenn Sie verschachtelte Kommentare zulassen möchten, dass Startkommentar-Tags mit einem Token markiert werden. Wenn ein Startkommentar-Tag also markiert ist, muss sein Endkommentar-Tag identisch markiert sein. Auf diese Weise können unausgeglichene Start- / End-Tags schnell identifiziert und die Möglichkeit von Fehlern vermieden werden, die durch unerkannte unausgeglichene Tags verursacht werden.
Supercat

Antworten:

6

Eine Sache, die noch niemand erwähnt hat, werde ich erwähnen: Der Wunsch, Kommentare zu verschachteln, deutet oft darauf hin, dass der Programmierer es falsch macht.

Lassen Sie uns zunächst annehmen, dass der Programmierer nur dann "verschachteln" oder "nicht verschachteln" kann, wenn der Programmierer strukturell Folgendes schreibt:

do_something();
/* comment /* nested comment */ more comment */
do_something_else();

Wann taucht so etwas in der Praxis auf? Mit Sicherheit wird der Programmierer keine verschachtelten Kommentare schreiben, die im wahrsten Sinne des Wortes wie das obige Snippet aussehen! Nein, in der Praxis, wenn wir Kommentare verschachteln (oder wünschen, dass wir sie verschachteln könnten), möchten wir Folgendes schreiben:

do_something();  /* do a thing */
/* [ajo] 2017-12-03 this turned out to be unnecessary
do_something_else(); /* do another thing */
*/

Und das ist SCHLECHT. Dies ist kein Muster, das wir (als Sprachdesigner) fördern wollen! Der richtige Weg, um das obige Snippet zu schreiben, ist:

do_something();  /* do a thing */

Dieser "falsche" Code, dieser Fehlstart oder was auch immer, gehört nicht in die Codebasis. Es gehört bestenfalls in die Versionsverwaltungsgeschichte. Idealerweise würden Sie nie den falschen Code schreiben, oder? Und wenn der falsche Code dort einen Zweck erfüllt, indem die Betreuer gewarnt werden, ihn aus irgendeinem Grund nicht wiederherzustellen, ist dies wahrscheinlich eine Aufgabe für einen gut geschriebenen und absichtlichen Codekommentar. Der Versuch, "Don't Do X" auszudrücken, indem nur ein alter Code hinterlassen wird, der X ausführt, aber auskommentiert ist, ist nicht die lesbarste oder effektivste Methode, um Leute davon abzuhalten, X zu tun.

Das alles läuft auf eine einfache Faustregel hinaus, die Sie vielleicht schon einmal gehört haben: Kommentieren Sie Code nicht aus. ( Die Suche nach diesem Begriff wird eine aufdrehen Menge von Meinungen in Vereinbarung .)

Bevor Sie fragen: Ja, Sprachen wie C, C # und C ++ bereits dem Programmierer geben einen anderen zu Werkzeug „Kommentar out“ große Blöcke von Code: #if 0. Dies ist jedoch nur eine bestimmte Anwendung des C-Präprozessors, der für sich genommen ein großes und nützliches Werkzeug ist. Tatsächlich wäre es für eine Sprache äußerst schwierig und besonders schwierig, die bedingte Kompilierung mit #ifund dennoch ohne Unterstützung zu unterstützen #if 0.


Wir haben festgestellt, dass verschachtelte Kommentare nur relevant sind, wenn der Programmierer Code auskommentiert. und wir haben (im Konsens vieler erfahrener Programmierer) festgestellt, dass das Auskommentieren von Code eine schlechte Sache ist.

Um den Syllogismus zu vervollständigen, müssen wir akzeptieren, dass Sprachdesigner ein Interesse daran haben, gute Dinge zu fördern und schlechte Dinge zu entmutigen (vorausgesetzt, dass alle anderen gleich sind).

Im Fall von verschachtelten Kommentare, alles andere ist gleich - Sie sicher das ignorieren Nieder gestimmt Antworten , die Behauptung , dass verschachtelte Parsen /*irgendwie für den Parser „schwierig“ wäre. (Geschachtelte /*sind nicht schwerer als geschachtelte (, die fast jeder Parser auf der Welt bereits verarbeiten muss.)

Sollte es ein Sprachdesigner, wenn alles andere gleich ist, einfach machen , Kommentare zu verschachteln (dh Code auszukommentieren), oder schwierig? Denken Sie daran, dass das Auskommentieren von Code eine schlechte Sache ist.

QED


Fußnote. Beachten Sie, dass Sie verschachtelte Kommentare nicht zulassen

hello /* foo*/bar.txt */ world

ist ein irreführender "Kommentar" - es ist gleichbedeutend mit

hello bar.txt */ world

(was wahrscheinlich ein Syntaxfehler ist). Aber wenn Sie tun erlauben verschachtelte Kommentare, dann

hello /* foo/*.txt */ world

ist ein irreführender "Kommentar" - es ist gleichbedeutend mit

hello

Der Kommentar bleibt jedoch bis zum Ende der Datei offen (was wiederum mit ziemlicher Sicherheit ein Syntaxfehler ist). Daher ist keiner der Wege besonders anfällig für ungewollte Syntaxfehler. Der einzige Unterschied besteht darin, wie sie mit dem absichtlichen Antipattern von auskommentiertem Code umgehen .

Quuxplusone
quelle
1
Ich habe eine andere Meinung aufgrund der Tatsache - ich habe nicht alles gesehen (und du auch nicht). Während diese goldenen Regeln wie "Code nicht auskommentieren" gut aussehen, hat das Leben seine eigenen Wege. In diesem speziellen Fall mache ich es sehr oft als Schalter, wenn ich eine neue Funktion teste und inkrementell Code einführen muss, damit ich den Code auskommentiere, dann weniger, weniger, weniger und schließlich habe ich Werkstück und ich kann alle Kommentare entfernen (über Code). Meine perfekte Sprache unterstützt natürlich verschachtelte Kommentare :-).
Greenoldman
@greenoldman: Die meisten Sprachen haben keine verschachtelbaren Kommentare, aber sie haben eine aktuelle Funktion zum "Entfernen eines Codeblocks", die weniger verwendet wird als die Funktion "Hinterlasse einen Kommentar". C #if DEADist das kanonische und am besten gestaltete Beispiel. In vielen Sprachen können Sie den toten Code einfach in das Äquivalent von umbrechen if (DEAD). In vielen IDEs können Sie den toten Code tatsächlich entfernen und sich auf Strg + Z und / oder die Versionskontrolle verlassen, um ihn zurückzugewinnen, wenn Sie möchten. Wenn Sie einen Kommentar hinterlassen, ist docstring, dessen Text eine Menge toten Codes enthält, immer noch die schlechteste Option für die Lesbarkeit.
Quuxplusone
11

Da die meisten Implementierungen separate Stufen für Lexing und Parsing verwenden und für Lexing einfache alte reguläre Ausdrücke verwenden. Kommentare werden als Leerzeichen behandelt, dh ignorierte Token, und sollten daher vollständig in einem Lexing-Durchgang aufgelöst werden. Der einzige Vorteil dieses Ansatzes ist die Analysegeschwindigkeit. Zu den zahlreichen Nachteilen gehören schwerwiegende Einschränkungen der Syntax (z. B. die Notwendigkeit, einen festen, kontextunabhängigen Satz von Schlüsselwörtern zu verwalten).

SK-Logik
quelle
3
Ich würde heutzutage in den meisten Punkten anderer Meinung sein. Sicherlich ist das der traditionelle Weg, aber ich weiß, dass EDG für C den Präprozessor, Lexing und Parsing kombiniert, und ich vermute, dass sowohl GCC als auch Microsoft dies auch tun. Der Vorteil ist, dass Sie sie bei Bedarf separat implementieren können.
Andrew Aylett
Clang macht das auch. Aber das ist immer noch nur ein winziger Teil der vorhandenen Compiler für populäre Sprachen.
SK-logic
@Neil Butterworth, werfen Sie einen Blick auf mcs, javac, gcc (yep, es repariert einen Lexer, aber es ist immer noch ein dedizierter Lexerpass), clang (wie gcc), dmd, fpc und viele, viele mehr.
SK-logic
Niemand verwendet reguläre Ausdrücke in seiner Lexierung für einen nicht trivialen Compiler.
Nuoji
@Nuoji - für den Nicht-Trivialen - sicher. Aber diejenigen, die sich auf flexible und ähnliche Tools verlassen, tun dies auch.
SK-logic
7

Es ist durchaus möglich, ein Lexer zu erstellen, das verschachtelte Kommentare verarbeiten kann. Wenn es Leerzeichen frisst, wenn es sieht /*, kann es einen Tiefenzähler inkrementieren und dekrementieren, wenn es sieht */, und anhalten, wenn die Tiefe Null ist. Trotzdem habe ich viele Parser durchgeführt und nie einen guten Grund gefunden, Kommentare zu verschachteln.

Wenn Kommentare verschachtelt werden können, ist es einfach, ihre Enden aus dem Gleichgewicht zu bringen. Wenn Sie keinen ausgefallenen Editor haben, kann er Code unsichtbar verbergen, von dem Sie annehmen, dass er vorhanden ist.

Ein Vorteil von Kommentaren, die nicht verschachtelt sind, ist wie folgt:

/*
some code
more code
blah blah blah
/**/

Hier können Sie den Code einfach durch Entfernen oder Hinzufügen der ersten Zeile auskommentieren - eine einzeilige Bearbeitung. Wenn dieser Code selbst einen Kommentar enthält, funktioniert dies natürlich nur, wenn Sie dort auch //Kommentare im C ++ - Stil zulassen . Das ist es, was ich tue.

Mike Dunlavey
quelle
1
//Kommentare sind ebenfalls C99-artig.
JAB
Alternativ könnte eine Sprache angeben, dass ein Kommentaranfang /*$token, identifierein alphanumerisches Token und ein Kommentarende ist token$*/. Für den Tokenizer ist es relativ einfach, Code einzuschließen, um zu überprüfen, ob jede Endkommentarmarkierung das richtige Token für den entsprechenden Startkommentarblock enthält.
Supercat
5

Da es sonst niemand erwähnte, liste ich einige Sprachen auf, die verschachtelte Kommentare unterstützen: Rexx, Modula-2, Modula-3, Oberon. Trotz aller Beschwerden über Schwierigkeiten und Geschwindigkeitsprobleme scheint keines von diesen irgendwelche großen Probleme zu haben.

Rugxulo
quelle
4
Dazu noch: Haskell, Frege
Ingo
Auch von Scala unterstützt.
Matt R
4

Ein guter Punkt beim Verschachteln von Blockkommentaren ist, dass Sie große Teile des Codes leicht auskommentieren können (fast, es sei denn, Sie haben die Blockkommentar-Endsequenz in einer Zeichenfolgenkonstante).

Eine alternative Methode besteht darin, ein paar Zeilen mit der Startsequenz des Zeilenkommentars voranzustellen, wenn Sie einen Editor haben, der dies unterstützt.

Haskell hat geschachtelte Blockkommentare, aber die meisten Leute scheinen es nicht zu bemerken oder sich darüber zu beschweren. Ich schätze, das liegt daran, dass Leute, die keine verschachtelten Kommentare erwarten, diese eher meiden, da dies in anderen Sprachen ein lexikalischer Fehler wäre.

Ingo
quelle
3

Das Unterstützen verschachtelter Blockkommentare erschwert den Parser, was mehr Arbeit bedeutet und die Kompilierzeit erhöhen kann. Ich denke, es ist kein sehr notwendiges Feature für eine Sprache, deshalb ist es besser, Zeit und Mühe für andere Verbesserungen und Optimierungen zu verwenden.

Meiner Meinung nach ist Einfachheit immer eine gute Sache, wenn man etwas entwirft. Beachten Sie, dass es einfacher ist, ein Feature hinzuzufügen, als es zu entfernen. Sobald Sie verschachtelte Kommentare zulassen und es Programme gibt, die sie verwenden, können Sie sie nicht mehr entfernen, ohne die Kompatibilität zu beeinträchtigen.

alexrs
quelle
1
+1 für "Ein Feature lässt sich leichter hinzufügen als entfernen".
R ..
3
/*/**/
Wenn
2

Ein möglicher Grund ist, dass verschachtelte Kommentare vom Parser behandelt werden müssen, da die in Lexern häufig verwendete Variante regulärer Ausdrücke keine Rekursion unterstützt. Die einfachen können vom Lexer als Leerzeichen entfernt werden, so dass sie auf diese Weise einfacher zu implementieren sind.

Hammar
quelle
3
Es ist nicht der "Geschmack". Das Wort "regulär" im regulären Ausdruck schließt von Natur aus eine Rekursion aus.
R ..
3
@R: In der Mathematik sicher. In der Programmierung gibt es jedoch Dinge, die wir reguläre Ausdrücke nennen, die die Rekursion unterstützen.
Amara
Die Frage ist: Ist das überhaupt ein Problem? Die meisten Sprachen müssen sich bereits mit geschachtelten Klammern auseinandersetzen. Um einige zu nennen: Lisp, C, Java, Python, Ruby, Perl.
Thomas Eding
Geschachtelte Klammern sind in Ordnung, da die Dinge in den Klammern die gleichen sind wie die Dinge außerhalb: normale Token. In Kommentaren haben Sie keine Token, Sie haben nur Text. Sie müssen in der Lage sein, die Start- und Endkommentartoken abzugleichen, damit Sie wissen, ob 'int' ein Typ oder nur ein Wort in einem Kommentar ist. (Vor allem, wenn Sie Kommentare im Lexer
entfernen
2
@ThePopMachine: Ich bin mir sicher, dass regular eine definierte formale Bedeutung hat, nicht die Bedeutung, die Sie verwenden, und dass "regular" in "regular expression" für diese Bedeutung ausgewählt wurde. Nicht rekursiv zu sein, ist ein Ergebnis seiner Definition.
R ..
-1

Wer weiß? Ich würde raten, weil das Unterstützen von verschachtelten Kommentaren mehr Arbeit bedeutet - Sie müssten einen Stapel von Kommentaren verwalten und weil dies die Sprachgrammatik kompliziert.

Neil Butterworth
quelle
-1

Verschachtelte Kommentare bedeuten zusätzliche Arbeit für den Parser. Wenn Sie den Anfang eines Kommentars sehen, ignorieren Sie normalerweise alles bis zur Endkommentarmarkierung. Um verschachtelte Kommentare zu unterstützen, müssen Sie den Text auch in den Kommentaren analysieren. Das größte Problem ist jedoch, dass ein Programmierer darauf achten muss, alle verschachtelten Kommentare korrekt zu schließen, da dies sonst zu Kompilierungsfehlern führt. Die ordnungsgemäße Implementierung eines Compilers ist zwar möglich, das Verfolgen verschachtelter Kommentare als Programmierer ist jedoch sehr fehleranfällig und irritierend.

Gus
quelle
3
-1: nicht wahr Vernünftige Parser funktionieren nicht so.
Amara