Closed bafto closed 1 year ago
Ich würde noch vorschlagen, dass wir Fehlermeldungen nummerieren, wie es viele andere Sprachen schon machen, um sie in der Bedienungsanleitung besser Dokumentieren zu können.
Ein System was mir momentan einfällt wäre:
<Fehlertyp><Fehlernummer>
Fehlertypen wären etwas wie:
So würde es dann zum Beispiel aussehen:
Fehler (S001): Eine Anweisung muss mit einem Punkt enden.
|
1 | Die Zahl z ist 0
|_________________^
in /test/test.ddp, Zeile: 1 Spalte: 17
Ein guter Teil des Issues wurde in new-error-handling abgearbeitet.
In dieser Branch wurde die neue (Rust-ähnliche) Fehler-Syntax implementiert.
Ich schlage vor die Branch in master zu mergen, diesen Issue zu schließen und die besseren Fehlermeldungen (den Text), und die Fehlertypen (Nummerierung) in einem anderen Issue und einer anderen Branch (oder Stück für Stück auf master) fortzusetzten.
Warum sollten wir nicht den gesamten Inhalt des Issues gleich in einer branch abarbeiten?
a) War nur ein eher kleiner Teil des Original Issues b) Die Fehler-Nachrichten selbst zu ändern kann nicht unabhängig geändert werden sondern greift (vor allem im Parser) in andere Teile des Compiler-Codes ein (aka wir werden wenn wir zu lange an dieser Branch arbeiten sehr viele Merge-Konflikte erhalten). c) Es ist eine schöne Aufteilung. Momentan haben wir die Visuelle Darstellung der Fehler schon verbessert, nun fehlen nur noch die Fehler selbst. Das kann man schön seperat machen indem man einmal alles durchgeht.
Okay, wir können einen weiteren Branch dafür machen und new-error-handling mergen, jedoch würde ich diesen Issue nicht schließen, da es allgemein um die Verbesserung der Fehlermeldungen geht. Also das Format und die Nachricht selbst.
Ich habe new-error-handling nach master gemerget. Ich denke wir können die branch dann einfach behalten und darauf mit den neuen Fehlermeldungen weiterarbeiten, da sie momentan up-to-date mit master ist.
Da das Format der Fehlermeldungen jetzt zufriedenstellend ist, geht es jetzt an die Nachrichten selbst.
Die Fehlermeldungen in Kategorien einzuteilen finde ich eine gute Idee. Erstmal würde ich folgende vorschlagen:
Weitere Kategorien können wir dann nach Bedarf hinzufügen wenn uns auffällt, dass es Sinn macht.
Zum Thema Fehler-Nummerieren bin ich mir nicht sicher. Es kommt mir nämlich irgendwie unnötig vor. Der einzige Vorteil, der mir einfällt wäre eine Große Fehlerliste in der Bedienungsanleitung wo man eine detaillierte Beschreibung hat und da halt die Nummer nachschlagen kann. Allerdings sollte der Fehler selbst zusammen mit dem Kontext des Codes ja schon so aussagekräftig sein, dass man nichts mehr nachschauen muss.
Zu den Meldungen an sich: Momentan gibt es noch sehr viele generische Meldungen wie "Es wurde X erwartet aber Y gefunden". Ich glaube so etwas lässt sich nicht vermeiden, aber wir können ja versuchen sie so gut es geht zu vermeiden.
Zum Thema Fehler-Nummerieren bin ich mir nicht sicher. Es kommt mir nämlich irgendwie unnötig vor. Der einzige Vorteil, der mir einfällt wäre eine Große Fehlerliste in der Bedienungsanleitung wo man eine detaillierte Beschreibung hat und da halt die Nummer nachschlagen kann. Allerdings sollte der Fehler selbst zusammen mit dem Kontext des Codes ja schon so aussagekräftig sein, dass man nichts mehr nachschauen muss.
Ich fand es immer nützlich, dass man einen Fehler-Code googlen oder den Fehler-Code mit anderen teilen konnte, statt den Fehler-Text zu benutzen, welcher oft auf einer anderen Sprache Lokalisiert wurde. Es sollte ja nicht so schwer zu sein ein Fehler-Code an den Text anzuhängen.
Dann Ordnen wir jedem Fehler einen Code zu.
Momentan sieht eine Fehlermeldung so aus:
Fehler in test.ddp (Z 2, S 18)
2 | Erhöhe x um 1.
| ^
Am Ende einer Funktion die etwas zurück gibt muss eine Rückgabe stehen.
------------------
Mit Fehlercodes würde ich dann das vorschlagen:
Semantischer/Syntax/Typ/... Fehler (122) in test.ddp (Z 2, S 18)
2 | Erhöhe x um 1.
| ^
Am Ende einer Funktion die etwas zurück gibt muss eine Rückgabe stehen.
------------------
Dabei würden dann z.B. alle Codes von 0 bis 99 für Syntaxfehler, von 100 bis 199 für Semantikfehler, etc. stehen. Ich glaube nicht, dass wir in einer Kategorie mehr als 100 Fehler-Arten haben werden. Die Fehlercodes sollten dann eher generisch sein (z.B. "type-mismatch" in anderen Sprachen wäre ein Code oder "Es wurde ./,/:/etc erwartet" wäre einer) und die Nachrichten spezieller (also verschiedene Arten von Nachrichten für "type-mismatch" aber nur 1 Code).
Die Fehlercodes sind jetzt auf der Branch new-error-handling implementiert. Für eine Liste der Codes siehe codes.go. Eine typische Fehlermeldung sieht jetzt in etwa so aus: test.ddp:
Die Funktion add mit den Parametern x und y vom Typ Zahl und Zahl, gibt eine Zahl zurück, macht:
Gib x plus y zurück.
Und kann so benutzt werden:
"add <x> <y>"
Die Kommazahl f ist add 1 2.
Ausgabe von $ kddp kompiliere test.ddp
:
Typ Fehler (3001) in test.ddp (Z: 6, S: 21)
6 | Die Kommazahl f ist add 1 2.
| ^^^^^^^
Ein Wert vom Typ Zahl kann keiner Variable vom Typ Kommazahl zugewiesen werden.
----------------------------
Damit bin ich in soweit zufrieden. Was noch fehlt ist eine Liste der Fehlercodes mit einer kurzen Erklärung und Beispielen in der Bedienungsanleitung, und ein Update des Language-Servers damit er Fehlercodes benutzt (das dürfte aber schnell gemacht sein).
Natürlich können viele (wenn nicht sogar die meisten) Fehlermeldungen noch deutlich verbessert werden, aber das ist ein Problem, das sich mit der Zeit und mit mehr DDP-Code löst, darum denke ich nicht, dass man dafür eine seperate Branch braucht.
Damit merge ich jetzt new-error-handling in master und schließe den Issue.
Zusammenfassung
Gute Fehlermeldungen sind essenziell um eine gute Entwicklererfahrung zu ermöglichen. Gerade für neue/kleine Sprachen ist sind sie wichtig um potentielle Nutzer nicht abzuschrecken. Die momentanen Fehlermeldungen von DDP sind zwar nicht so schlimm wie C++-template-error-messages, aber sind auch nicht gerade gut und definitiv verbesserungswürdig.
Problem
Momentan sind DDP Fehlermeldungen meist kryptisch, zu lang/kurz oder schlichtweg falsch. Oft weisen sie auf ein Problem hin, das an ganz anderer Stelle liegt und sind somit nicht sehr hilfreich. Zudem sind die Formulierungen nicht sehr verständlich wenn man den Kompilierer nicht kennt, da die meisten Fehlermeldungen während des Entwickelns, oftmals temporär als Platzhalter, recht schnell und rudimentär geschrieben wurden.
Inspiration von Rust
Viele Developer (ja, ich meine dich @NotLe0n) sind begeistert von den Fehlermeldungen, die der Rust-Compiler bereitstellt. Diese enthalten folgende auffallende Features:
Diese Eigenschaften von Rust Fehlermeldungen scheinen viele Entwickler zu begeistern und könnten auch in DDP integriert werden.
Implementation / Schwierigkeit
Die Fehlermeldungen selbst kann man definitv verbessern indem man sich einfach einmal Zeit nimmt und alles durchgeht bzw. Fehlermeldungen hinzufügt. Code-Snippets wie in Rust sollten mit ein wenig Aufwand auch gut machbar sein. Eventuell können wir einfach Rusts Format kopieren. Verbesserungsvorschläge sind schon schwieriger. Sie erfordern ein sehr gutes Verständnis des Quellcodes, welches der Kompilierer im Moment nicht immer besitzt. Zudem sind sie ein zwar tolles Feature, aber nicht unbedingt notwending. Wenn die Fehlermeldung selbst gut genug ist, kann man Fehler auch selbst erkennen und fixen. Verbesserungsvorschläge können wir also für Spätere Releases im Hinterkopf behalten.