In Eric Lipperts Artikel What's Up With Hungarian Notation? , erklärt er, dass der Zweck der ungarischen Notation (der guten Art) darin besteht,
Erweitern Sie das Konzept von "Typ", um zusätzlich zu Speicherrepräsentationsinformationen auch semantische Informationen zu erfassen.
Ein einfaches Beispiel wäre das Präfixieren einer Variablen, die eine X-Koordinate darstellt, mit "x" und einer Variablen, die eine Y-Koordinate darstellt, mit "y", unabhängig davon, ob diese Variablen Ganzzahlen oder Gleitkommazahlen sind oder was auch immer, so dass Sie versehentlich schreiben xFoo + yBar
sieht der Code eindeutig falsch aus.
Aber ich habe auch über das Typensystem von Haskell gelesen, und es scheint, dass man in Haskell dasselbe erreichen kann (dh "das Konzept des Typs auf semantische Informationen erweitern"), indem man tatsächliche Typen verwendet , die der Compiler für Sie prüft. Im obigen Beispiel xFoo + yBar
würde Haskell die Kompilierung tatsächlich fehlschlagen, wenn Sie Ihr Programm korrekt entworfen hätten, da sie als inkompatible Typen deklariert würden. Mit anderen Worten, es scheint, als ob das Typensystem von Haskell die Prüfung zur Kompilierungszeit unterstützt, die der ungarischen Notation entspricht
Ist die ungarische Notation also nur ein Hilfsmittel für Programmiersprachen, deren Typsysteme keine semantischen Informationen codieren können? Oder bietet die ungarische Notation etwas, das über das hinausgeht, was ein statisches Typensystem wie das von Haskell bietet?
(Natürlich verwende ich Haskell als Beispiel. Ich bin mir sicher, dass es andere Sprachen mit ähnlich ausdrucksstarken (reichen? Starken?) Systemen gibt, obwohl ich keine gefunden habe.)
Der Einfachheit halber spreche ich nicht von der Annotation von Variablennamen mit dem Datentyp , sondern von Informationen über die Bedeutung der Variablen im Kontext des Programms. Beispielsweise kann eine Variable eine Ganzzahl oder ein Gleitkomma oder ein Double oder ein Long sein, aber die Variable hat möglicherweise die Bedeutung, dass es sich um eine relative x-Koordinate handelt, die in Zoll gemessen wird. Dies ist die Art von Informationen, die ich über die Codierung in ungarischer Notation (und über Haskell-Typen) spreche.
quelle
Antworten:
Ich würde Ja sagen".
Wie Sie sagen, besteht der Zweck der ungarischen Notation darin, Informationen in dem Namen zu codieren, die im Typ nicht codiert werden können. Grundsätzlich gibt es jedoch zwei Fälle:
Beginnen wir mit Fall 2: Wenn diese Informationen nicht wichtig sind, ist die ungarische Notation einfach überflüssiges Rauschen.
Der interessantere Fall ist Nummer 1, aber ich würde argumentieren, dass wenn die Informationen wichtig sind, sie überprüft werden sollten, dh sie sollten Teil des Typs sein , nicht des Namens .
Das bringt uns zurück zum Eric Lippert Zitat:
Eigentlich, das ist nicht „ das Konzept vom Typ“, das ist das Konzept der Art! Der gesamte Zweck von Typen (als Entwurfswerkzeug) besteht darin, semantische Informationen zu codieren! Speicher Darstellung ist eine Implementierung Detail , das in der Regel nicht in der Art gehört überhaupt . (Und speziell in einer OO-Sprache kann man nicht in den Typ gehören, da die Repräsentationsunabhängigkeit eine der Hauptvoraussetzungen für OO ist.)
quelle
S1
der einzige Verweis irgendwo im Universum auf einen istchar[]
, dessen Inhaber ihn jederzeit ändern kann und wird, aber niemals externem Code aussetzen darf,S2
ist dies ein Verweis auf einen,char[]
den niemand jemals ändern sollte, der jedoch gemeinsam genutzt werden kann mit Objekten, die versprechen, es nicht zu ändern, sollteS1
undS2
sollte semantisch als die gleiche "Art der Sache" angesehen werden?Der gesamte Zweck von Typen (als Entwurfswerkzeug) besteht darin, semantische Informationen zu codieren!
Ich mochte diese Antwort und wollte diese Antwort weiterverfolgen ...
Ich weiß nichts über Haskell, aber Sie können so etwas wie das Beispiel von
xFoo + yBar
in jeder Sprache ausführen, die eine Form der Typensicherheit wie C, C ++ oder Java unterstützt. In C ++ können Sie XDir- und YDir-Klassen mit überladenen '+' - Operatoren definieren, die nur Objekte ihres eigenen Typs akzeptieren. In C oder Java müssten Sie Ihre Addition mit einer Funktion / Methode add () anstelle des Operators '+' durchführen.Ich habe immer die ungarische Notation für Typinformationen gesehen, nicht die Semantik (außer, wenn die Semantik durch den Typ dargestellt werden könnte). Eine bequeme Möglichkeit, sich den Typ einer Variablen in den Tagen vor "intelligenten" Programmiereditoren zu merken, die den Typ auf die eine oder andere Weise rechts im Editor anzeigen.
quelle
xFoo + yBar
benutzerdefinierte Typen zulässt , noch muss der OO-Aspekt von C ++ funktionieren, damit dieses Beispiel funktioniert.xFoo + yBar
einen Kompilierungsfehler (oder zumindest einen Laufzeitfehler) in so ziemlich jeder Sprache machen können. Wäre Mathematik mit XDir- und YDir-Klassen in Java oder C ++ jedoch langsamer als Mathematik mit rohen Zahlen? Ich verstehe, dass in Haskell die Typen zur Kompilierungszeit überprüft werden und dass es dann zur Laufzeit nur rohe Mathematik ohne Typüberprüfung und daher auch nicht langsamer als das Hinzufügen regulärer Zahlen ist.XCoordinate
beispielsweise ein Int nicht als regulär behandeln .Mir ist klar, dass der Ausdruck "Ungarische Notation" etwas anderes bedeutet als das Original , aber ich werde die Frage mit "Nein" beantworten. Das Benennen von Variablen mit semantischem oder rechnerischem Typ entspricht nicht dem SML- oder Haskell-Typ. Es ist nicht einmal ein Pflasterstein. Am Beispiel von C könnten Sie eine Variable gpszTitle nennen, aber diese Variable hat möglicherweise keinen globalen Gültigkeitsbereich und stellt möglicherweise nicht einmal einen Punkt auf eine nullterminierte Zeichenfolge dar.
Ich denke, die moderneren ungarischen Notationen weichen noch stärker von einem starken Typ-Deduktionssystem ab, weil sie "semantische" Informationen (wie "g" für global oder "f" für flag) mit dem rechnerischen Typ ("p" Zeiger, " i "integer, etc etc.) Das endet einfach als ein unheiliges Durcheinander, bei dem Variablennamen nur eine vage Ähnlichkeit mit ihrem Rechentyp haben (der sich mit der Zeit ändert) und alle so ähnlich aussehen, dass Sie nicht" next match "verwenden können finde eine Variable in einer bestimmten Funktion - sie sind alle gleich.
quelle
Die ungarische Notation wurde für BCPL erfunden, eine Sprache, die überhaupt keine Typen hatte. Oder besser gesagt, es hatte genau einen Datentyp, das Wort. Ein Wort kann ein Zeiger oder ein Zeichen oder ein Boolescher Wert oder eine einfache Ganzzahl sein, je nachdem, wie Sie es verwendet haben. Offensichtlich war es dadurch sehr einfach, schreckliche Fehler wie die Dereferenzierung eines Charakters zu machen. So wurde die ungarische Schreibweise erfunden, damit der Programmierer zumindest eine manuelle Typprüfung anhand des Codes durchführen konnte.
C, ein Abkömmling von BCPL, hat unterschiedliche Typen für Ganzzahlen, Zeiger, Zeichen usw. Dies machte die ungarische Grundnotation zu einem gewissen Grad überflüssig (Sie mussten den Variablennamen nicht codieren, wenn es ein Int oder ein Zeiger war). Eine darüber hinausgehende Semantik konnte jedoch nicht als Typ ausgedrückt werden. Dies führte zur Unterscheidung zwischen "Systems" und "Apps" Ungarisch. Sie mussten nicht ausdrücken, dass eine Variable ein Int ist, aber Sie können mithilfe von Codebuchstaben angeben, ob das Int eine X- oder Y-Koordinate oder ein Index ist.
In moderneren Sprachen können benutzerdefinierte Typen definiert werden. Dies bedeutet, dass Sie die semantischen Einschränkungen in den Typen und nicht in den Variablennamen codieren können. Beispielsweise hat eine typische OO-Sprache bestimmte Typen für Koordinatenpaare und Flächen, sodass Sie vermeiden, einer y-Koordinate eine x-Koordinate hinzuzufügen.
In Joels berühmtem Artikel , in dem er Apps Hungarian lobt, verwendet er beispielsweise das Präfix
us
für eine unsichere Zeichenfolge unds
eine sichere (HTML-codierte) Zeichenfolge, um HTML-Injection zu verhindern. Der Entwickler kann HTML-Injection-Fehler verhindern, indem er einfach den Code sorgfältig überprüft und sicherstellt, dass die variablen Präfixe übereinstimmen. Sein Beispiel ist VBScript, eine veraltete Sprache, die anfangs keine benutzerdefinierten Klassen zuließ. In einer modernen Sprache kann das Problem mit einem benutzerdefinierten Typ behoben werden, und genau das macht Asp.net mit derHtmlString
Klasse. Auf diese Weise findet der Compiler den Fehler automatisch, was viel sicherer ist, als sich auf menschliches Augapfel zu verlassen. Eine Sprache mit benutzerdefinierten Typen macht also in diesem Fall "Apps Hungarian" überflüssig.quelle
Ja, obwohl viele Sprachen, die ansonsten stark genug sind, immer noch ein Problem haben - die Ausdruckbarkeit neuer Typen, die auf vorhandenen Typen basieren oder diesen ähneln.
In vielen Sprachen, in denen wir das Typensystem mehr verwenden könnten, tun wir dies nicht, weil der Aufwand, einen neuen Typ zu erstellen, der im Grunde genommen mit einem vorhandenen Typ mit Ausnahme von name und einigen Konvertierungsfunktionen identisch ist, zu groß ist.
Im Wesentlichen benötigen wir eine Art stark typisierter typedefs, um die ungarische Notation in diesen Sprachen vollständig zu töten (F # style UoM könnte dies auch tun).
quelle
Denken Sie daran, es gab eine Zeit, in der IDEs keine Popup-Hinweise zum Typ einer Variablen hatten. Es gab eine Zeit, in der IDEs den Code, den sie bearbeiteten, nicht verstanden, sodass Sie nicht einfach von der Verwendung zur Deklaration wechseln konnten. Es gab auch eine Zeit, in der Sie einen Variablennamen nicht umgestalten konnten, ohne die gesamte Codebasis manuell zu durchlaufen, die Änderung manuell vorzunehmen und zu hoffen, dass Sie keinen verpasst haben. Suchen & Ersetzen konnte nicht verwendet werden, da bei der Suche nach Kunde auch der Kundenname angezeigt wird.
In diesen dunklen Tagen war es hilfreich zu wissen, welcher Typ eine Variable war, in der sie verwendet wurde. Wenn richtig gepflegt (ein GROSSES wenn wegen des Mangels an Refactoring-Tools), gab Ihnen die ungarische Notation das.
Die Kosten für die schrecklichen Namen, die es in diesen Tagen hervorbringt, sind zu hoch, aber das ist eine relativ junge Sache. Es gibt immer noch viel Code, der älter ist als die von mir beschriebenen IDE-Entwicklungen.
quelle
Richtig!
Außerhalb völlig untypisierter Sprachen wie Assembler ist die ungarische Notation überflüssig und ärgerlich. Zweifelsohne, wenn Sie bedenken, dass die meisten IDEs die Typensicherheit prüfen, während Sie tippen.
Das zusätzliche "i" "d" und "?" Präfixe machen den Code nur weniger lesbar und können wirklich irreführend sein - wie wenn ein "Cow-Orker" den Typ von iaSumsItems von Integer auf Long ändert, sich aber nicht darum kümmert, den Feldnamen umzugestalten.
quelle