Programmier Stil Alpha Diskussion
 
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern

Von ProgrammierStilAlpha

Übersetzbare Bezeichner
typedef struct Word
{
  char  *spelling;          /* spelling of the word */
  unsigned short type;      /*
                             * type of the word
                             * possible values are:
                             * 0 = unknown
                             * 1 = noun
                             * 2 = verb
                             * 3 = article
                             * ...
                             */
 unsigned short flags;       /*
                             * further classification, dependent
                             * on the type
                             */
} Word; 

.
.
.

Word word;

Würde das dem obigen Absatz widersprechen? Kleine Korrekturen ok (_ am Bezeichneranfang ist laut Standard für das System reserviert)? Nein, da würde nichts widersprechen.


Dictionary

Konsistente Funktionsnamen

Also z.B. WindowSetTitelText(window,titel,text) und nicht WindowSetTitelText(window,text,titel). Als Beispiel die Inkonsistenz zwischen der (nach dieser Regel korrekten) C-Funktion fprintf(file,format,...) und der diese Regel verletzenden Funktion fgets(buffer,buffersize,file). Die letztere Funktion könnte in einem konformen System z.B. FileReadBufferSize(file,buffer,size) oder verkürzt FileReadBuffer(file,buffer,size) lauten.

  FileReadBufferSize(inputFile, textBuf, TEXT_BUF_SIZE); 
  FileReadBufferSizeFilter(inputFile, textBuf, TEXT_BUF_SIZE, ascciFilter); 
  StringReadBufferSize(inputText, textBuf, TEXT_BUF_SIZE); 
  StringReadBufferSizeFilter(inputText, textBuf, TEXT_BUF_SIZE, ascciFilter); 

  ReadBuffer(inputFile, textBuf, TEXT_BUF_SIZE); 
  ReadBuffer(inputFile, textBuf, TEXT_BUF_SIZE, ascciFilter); 
  ReadBuffer(inputText, textBuf, TEXT_BUF_SIZE); 
  ReadBuffer(inputText, textBuf, TEXT_BUF_SIZE, ascciFilter); 
Wenn man kompatibel zu verschieden Sprachen bleiben muß, steht overloading natürlich nicht zur Verfügung. Dann würde ich die Namen wie folgt wählen:
  ReadBufferOfSizeFromFile(textBuf, TEXT_BUF_SIZE, inputFile); 
  ReadBufferOfSizeFromFileWithFilter(textBuf, TEXT_BUF_SIZE, inputFile, ascciFilter); 
  ReadBufferOfSizeFromString(textBuf, TEXT_BUF_SIZE, inputText); 
  ReadBufferOfSizeFromStringWithFilter(textBuf, TEXT_BUF_SIZE, inputText, ascciFilter); 
Ich würde sogar auf den Size-Parameter ganz verzichten wollen. Als Regel könnte man formulieren:
Alle Parameter die für eine Routine notwendig sind, werden nicht in den Name der Routine integriert, es sei denn, sie werden benötigt, die Aufgabe der Routine zu beschreiben.
Eine Routine muß mir immer die Frage beantworten (so kurz wie möglich, so Ausagekräftig wie nötig) was tu ich wenn ich "dich" benutze. Und "Was tust du? ReadBufferFromFileWithFilter." erklärt mir mehr als ein"Was tust du? FileReadBufferSizeFilter.". Sonst fängt man wieder an Kommentare zu schreiben. :-) hz

Ein FileReadBuffer (mit seinen Varianten) ergibt sich aus der Ähnlichkeit mit Funktionen wie FileDelete, FileGetXyz oder FileRetSize. Dafür spricht die ermöglichte Isomorphie (mit File f; f.readBuffer, f.getXyz, ...). Dafür spricht auch das Ziel der alphabetische Nähe ähnlicher Funktionen (alle Funktionen mit Files beginnen mit File...) welches die Einarbeitung in ein großes API sehr erleichtert. -- HelmutLeitner

FileReadBuffer ist ja noch okay. Die Argumente, das "File" vorne stehen soll, kann ich schon nachvollziehen (man sollte aber dann noch anmerken das copyStringBuffer unter diesem Gesichtspunkt Mist ist). Mich stört mehr, dass Funktionsvarianten einfach um den Namen der zusätzlichen Parameter ergänzt werden sollen. Die Namen die dabei entstehen können verwirrend sein. ReadBufferSize sollte eine Puffergrösse einlesen und nicht n-Bytes in einen Puffer. Ich finde den ProgrammierStilAlpha übrigens ganz gut (speziell bezogen auf seine Ansprüche). Eine theoretische Diskussion ist wahrscheinlich gar nicht sinnvoll. Besser wäre es konkrete Probleme bei der Namensvergabe im Projekt zu diskutieren und deren Ergebnisse als Beispiele oder Ausnahmen bei den entsprechenden Regeln zu hinterlegen. hz

  • Obiger Zusatz ok?
    • Das Problem ist, das, wenn man diesen Freiheitsgrad zuläßt, das System nicht mehr konsistent ist. Wenn ich dich richtig verstanden habe, spiegelt die Reihenfolge der Worte in den Namen die Reihenfolge der Funktionsargumente wider. Wenn das so ist, dann kann man bei einer Funktion mit dem Argument size das Wort Size nicht fortlassen, wenn auch eine andere Parametrisierung möglich ist, wie z.B. bei Strings, deren Länge durch das Endezeichen implizit ermittelt werden kann. Läßt man Verkürzungen in diesem Bereich zu, führt das meiner Meinung nach unweigerlich zu Ausnahmeregeln, wodurch ein solches Konstrukt unnötig kompliziert wird
  • Gewisse Verkürzungen sind bei OO-Sprachen unausweichlich (bei Konstruktoren). Während eine prozedurale Sprache unterscheiden kann zwischen buffer=BufferNewSize(size) und buffer=BufferNewFileNa(filename), ist das bei Java-Konstruktoren nicht möglich: buffer=new Buffer(size) bzw. buffer=new Buffer(filename). Wenn es einem sympathisch ist, kann man aber solche prozeduralen Wrapper-Funktionen zusätzlich über die Konstruktoren "stülpen"!? [Was übrigens eine beliebte Methode ist um VirtuelleKonstruktoren? zu implementieren. Auf Request liefere ich eine Beschreibung nach (nicht jetzt, um 00:00 Ortszeit)]

Verwendung einer GUI-Beschreibungssprache

Alignment bei Strukturen
  struct {
     char string1[7];
     char string2[11];
     char string3[13];
  };
Oder habe ich was mißverstanden?

Kopf
typedef struct _HeaderOfLexicon
{
           char  version,
                 release,
                 OS,
                 reserved1[13];
           short numberOfTypes,
                 numberOfAreas,
                 maxTypesOfWord,
                 reserved2[4];
  unsigned short checkEndian;
           long  beginOfLexicalEntries,
                 numberOfWords,
                 sizeOfDescription,
                 reserved3[5];
} HeaderOfLexicon;

Datensatz
typedef struct _LexicalEntry
{
  long  index,                /* start of the description */
        attribute;            /* bitfield for global attributes */
                              /* the values are not compressed yet ... */
  short type,                 /* type of the lexical entry */
        area,                 /* area of usage of the lexical entry */
        numberOfCorrections;  
} LexicalEntry;

Die erste Struktur ist 64 Byte groß und beschreibt den Inhalt der lexikalischen Datei, die zweite Struktur ist 14 Byte groß und beschreibt die einzelnen Einträge in der lexikalischen Datei. Dazu kommen noch ein paar Blöcke mit den Worttypen, den Gebieten, den globalen Attributen und natürlich den Beschreibungen der Worte. Diese Daten werden genauso in die Datei geschrieben, wie sie im RAM vorliegen. Ferner können die Dateien entweder auf verschiedenen Rechnern lokal vorliegen oder aber auch auf einem zentralen Server, wo sie per NFS o. ä. in einem großen Netzwerk verfügbar wären.
Wenn diese Strukturen kein korrektes align hätten, gäbe es Probleme, mit unterschiedlichen Prozessoren zu arbeiten, da einige Prozessoren z.B. Langworte nur auf durch 4-teilbaren Adressen verwenden können, andere kommen mit geraden Adressen klar und wieder andere kommen mit jeder Adresse klar (ich weiß im Moment aber nicht genau, welche das sind).

Keine unübertragbaren Sprachelemente
Was bleibt dann als Schnittmenge dieser verschiedenenen Sprachen noch übrig? -- MichaelButscher Beispiele für "Löcher"/Probleme mit verschiedenen Programmiersprachen

1. Du wolltest eine Gui-Beschreibungssprache verwenden. Sollen dann für alle Sprachen passende Interpreter implementiert werden? Das allein ist ein Großprojekt.
2. Java bräuchte z. B. Unterstützung für regular expressions. Es gibt zwar solche Bibliotheken, aber es müssen natürlich Wrapperfunktionen mit den passenden Namen gemäß dieses Standards geschrieben werden. In Perl müssen dann genauso Wrapperfunktionen mit gleichen Namen benutzt werden. Das führt letztlich dazu, daß ein Perl-Programmierer regexps nicht mehr auf die "natürliche Art" nutzen darf (irgendwas mit "=~" oder "s/.../.../" zum Beispiel).

Perl:
  string =~ s/Maier/Müller/;
Java:
  string.ReplaceRegex("/Maier/Müller/");
C:
  StringReplaceRegex(string,"/Maier/Müller/");
würde das in Perl nicht schaden, den anderen Sprachen nur gut tun. Es geht sicherlich nicht darum, mutwillig bürokratische, einengende Regeln zu erzeugen.

3. Java-Programmierer andererseits dürfen synchronized-Blöcke nicht mehr verwenden, weil es die in Basic nicht gibt usw ... -- mb
Zu Exceptions

Verschoben nach ExceptionsDiskussion


Allgemeine Anmerkungen

Zunächst sollte geklärt werden, ob diese Standards für die Programmierung von Bibliotheken (bzw. eines Servers) oder für front-ends verwendet werden soll. Es sollte da verschiedene Standards geben, das back-end wird wohl kaum mit Perl oder Basic programmiert, warum also darauf Rücksicht nehmen? -- mb

Überhaupt scheint dieser Standard darauf abzuzielen, das jeder Programmierer den ganzen Code lesen kann, auch wenn er die Sprache eigentlich nicht kennt. Das erscheint mir nicht sinnvoll. Er muß nur die API kennen und verwenden können. Welche sprachspezifischen Finessen im Inneren benutzt werden, muß er nicht wissen. -- mb
Binäre Dateiformate

<Adresse des Elements> modulo <Größe des Elements> = 0

genügt. Lücken sind mit reservierten Elementen explizit aufzufüllen.
Wäre SDXF eine Lösung? - http://www.ietf.org/rfc/rfc3072.txt (Max Wildgrube)
Strukturierte Programmierung
Es sollen die Regeln der strukturierten Programmierung eingehalten werden, jeder Block hat einen Eingang und einen Ausgang. Ein Block ist hierbei eine logische Einheit, wie z.B. ein Befehl, eine bedingte Anweisung, eine Schleife, eine Funktion oder ein Programm. Das Verlassen einer Schleife mittels break, das Abkürzen mittels continue u.a. sollte z.B. unterlassen werden, da es zumindest in komplexen Blöcken fehlerträchtig ist.
BEISPIEL_A:
READ_LINES_OF_FILE {
  PROCESS_LINE 
  ...(viele Zeilen)
}

BEISPIEL_B:
READ_LINES_OF_FILE {
  IF_COMMENT {
    continue;
  }
  PROCESS_LINE 
  ...(viele Zeilen)
}
Für mich ist B ein lokal begrenzter, sehr schonender Eingriff, der A erweitert. Für andere ist es schlechter, fehleranfälliger Stil. Es gibt immer wieder ReligionsKriege um solche Fragen.
Nun, ReligionsKriege will ich nicht gerade entfesseln (dazu bin ich viel zu friedlich), sondern eher potentielle Gefahrenquellen aufzeigen (ich spreche da nur aus leidvoller Erfahrung :-/ ). Ich sehe eine entsprechende Einrücktiefe einfach als das kleinere Übel an. In Maßen eingesetzt sind diese Befehle durchaus sinnvoll --- leider arbeiten sehr viele Entwickler mit amerikanischen Tastaturen und verwechseln daher Maßen mit Massen.
Wie wäre es mit breaks, continues, vorzeitige Returns oder Exits sollten nur sehr sparsam verwendet und müssen auffällig kommentiert werden. Die Fehleranfälligkeit resultiert daraus, daß man in komplexen Bereichen so ein kleines break halt sehr leicht übersieht. Im übrigen sollten die Richtlinien so ähnlich gesehen werden wie deine erste Regel zur SoftwareOptimierung: Man sollte sich danach richten, aber wenn man genau weiß, was man tut, kann man ab und zu mal dagegen verstoßen. Gewisse Freiheitsgrade sollten schon möglich sein, aber das Ausnutzen sollte dann auch genau dokumentiert werden.

Gegebeispiel:

BEISPIEL_A:
READ_LINES_OF_FILE {
  PROCESS_LINE ( data )
}

BEISPIEL_B:
READ_LINES_OF_FILE {
  IF_COMMENT {
    continue;
  }
  PROCESS_LINE ( data )
}

BEISPIEL_C:
READ_LINES_OF_FILE {
  ENTSCHEIDE ( ERSTER_BUCHSTABE ) {
    #: break
    0-9: PROCESS_NUMBER ( data )
    a-z: PROCESS_ALPHA ( data )
    default: SYNTAX_ERROR
  }
}

BEISPIEL_D: bison/yacc


KategorieDiskussion KategorieProgrammierStil
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 14. Januar 2004 12:20 (diff))
Suchbegriff: gesucht wird
im Titel
im Text