Das Rad neu erfinden - Parameter auf Kommandozeile

Algorithmen, Sprachunabhängige Diskussionen zu Konzepten, Programmiersprachen-Design
Antworten
Panke
Beiträge: 70
Registriert: So Nov 14, 2010 10:47 am

Das Rad neu erfinden - Parameter auf Kommandozeile

Beitrag von Panke » Mo Sep 05, 2011 5:57 pm

Moin,

ich arbeite gerade Spaßeshalber an einer Bibliothek für das Parsieren von Parametern auf der
Kommandozeile. Ich orientiere mich dabei an Boost.Program_Options und an Pythons argparse.

Ich wollte trotzdem mal hören, was ihr von einer entsprechenden Bibliothek erwarten würdet.
Die Programmiersprache ist D. D und C++ sind sich aber ähnlich genug, dass ihr gerne
auch Senf zu einer C++-Implementierung abgeben könnt.

Ich habe folgende Punkte auf dem Zettel.
  • Typsicher
  • Unterstützung für --lange-optionen und -k urze optionen
  • Zusammenfassung kurzer Optionen. Aus -v -k -f wird -vkf
  • Einfache Erweiterung mit eigenen Datentypen.
  • Zählende Optionen (-vvv)
  • Unterstützung von --long-option=value und -s<value> und -fs<value>
  • Ein Erweiterungsmechanismus, der mindestens erlaubt, so Späße wie --enable-<option> --disable-option zu bauen. Falls man sowas haben will.
  • Automatisch generierte Hilfetexte
  • Gute Fehlermeldungen, falls die Kommandozeile falsch ist. Etwa. "myprog --size=a23" --> size: a23 kann nicht zu int konvertiert werden.
  • Erforderliche Optionen, Standardwerte.
  • Erweiterung um zum Beispiel Optionen aus einer Datei zu lesen möglich.
Was fällt euch noch ein? Im Moment sieh ein Beispielaufruf so aus:
http://paste.pocoo.org/show/470784/

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Das Rad neu erfinden - Parameter auf Kommandozeile

Beitrag von Xin » Di Sep 06, 2011 8:58 am

Ich finde "das Rad neu zu erfinden" ist der falsche Ausdruck.
Ich habe dieses Rad ebenfalls noch auf meiner Liste, weil dieses Rad bei meinem Compiler reichlich Ecken hat ;-)

Wenn Du für die Fehlermeldungen eine Formatierungs-Callback-Funktion baust, hättest Du eigentlich alles, was ich brauche.

Beispiel: Du möchtest den Fehler "size: a23 kann nicht zu int konvertiert werden" ausgeben, dann guckst Du, ob Du Dir Callback-Funktion bekannt ist:
[cod€]bool format( char const * param, char const * givenValue, enum ErrCode, char const ** addData, std::string & result )[/code]

Die könnte man dann so aufrufen:

Code: Alles auswählen

char const ** datatypes{ "int", "short", "string", NULL };

// ...

char data ** = { datatypes[0], NULL };
std::string output;

if( !formatCallback( param, value, CANNOT_CONVERT_TO_INT, data, output ) )
{
  internalFormat( param, value, CANNONT_CONVERT_TO_INT, data, output );
}

printError( output );
Nachvollziehbar?

Ich habe bei dem Compiler ein Standard-Ausgabeformat für Fehler. Nehmen wir an, ich würde Deine Lib benutzen, so würdest Du mit Deinem Ausgabeformat querschießen. Gibst Du mir die Möglichkeit, die Ausgabe selbst zu sortieren, dann könnte Dein Rad auf meinen Wagen passen. :-)

Wenn Du möchtest, richte ich Dir ein Subversion-Repository auf proggen.org dafür ein.

EDIT: Bei Bedarf kann ich Dir dann einige Tipps geben, wie Du ein solches Rad ziemlich rund bekommst (z.B. in dem Du keine Enums verwendest, wie ich das hier als Beispiel getan habe!)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Panke
Beiträge: 70
Registriert: So Nov 14, 2010 10:47 am

Re: Das Rad neu erfinden - Parameter auf Kommandozeile

Beitrag von Panke » Di Sep 06, 2011 9:28 am

Xin hat geschrieben:Ich finde "das Rad neu zu erfinden" ist der falsche Ausdruck.
Ich habe dieses Rad ebenfalls noch auf meiner Liste, weil dieses Rad bei meinem Compiler reichlich Ecken hat ;-)
In D besteht tatsächlich sogar Bedarf, wenn ich mir die Standardbibliothek angucke.
Wenn Du für die Fehlermeldungen eine Formatierungs-Callback-Funktion baust, hättest Du eigentlich alles, was ich brauche.
Ich möchte, dass man die Bibliothek am Ende für 90% der Fälle nutzen kann, ohne sich über irgendetwas
Gedanken machen, Sachen registrieren zu müssen, etc. Das gilt zunächst auch, wenn ich sie mit
eigenen Typen erweitere. Zur Zeit gibt es daher ein Template ValueSemantic(T). Das weiß, es gehört zu einer
Option, die einen Wert vom Typ T bekommen soll und parsiert den automatisch richtig. Die Standardbib
von D macht es möglich.

Daher kann ich momentan kein enum einbauen, das CONNOT_CONVERT_TO_INT als Wert hat, da ich die
Typen gerade als Template-Parameter habe.

Ich plane bereits jetzt mit einer ValueSemantic, die Erweiterungspunkte über Delegates (++function_pointer)
definiert. Sobald ich eine Basisfunktionalität fertig und aufgeräumt habe, zeige ich mal den aktuellen Stand her.
Dann kriegt man ein besseres Bild davon.

Dass alle Ausgaben vorher durch eine Formatter-Klasse laufen o.ä. behalte ich aber im Hinterkopf. Die kann
man dann ja austauschen, falls man unbedingt möchte.
Wenn Du möchtest, richte ich Dir ein Subversion-Repository auf proggen.org dafür ein.
Danke, aber ich nutze git und schieb den Kram immer auf einen eigenen Server bzw. github/gitorious.
EDIT: Bei Bedarf kann ich Dir dann einige Tipps geben, wie Du ein solches Rad ziemlich rund bekommst (z.B. in dem Du keine Enums verwendest, wie ich das hier als Beispiel getan habe!)
Freue mich über jeden Kommentar zur Implementierung. Da sind auch noch ein paar Fragen offen. Dazu mehr sobald das momentane Design vorzeigbar ist und die Basisfunktionalität schon mal stimmt.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Das Rad neu erfinden - Parameter auf Kommandozeile

Beitrag von Xin » Mo Sep 12, 2011 7:46 pm

Programmierst Du das ganze in D?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Panke
Beiträge: 70
Registriert: So Nov 14, 2010 10:47 am

Re: Das Rad neu erfinden - Parameter auf Kommandozeile

Beitrag von Panke » Mo Sep 12, 2011 9:28 pm

Ja, ich wollte mir D mal angucken. Siehe Beispielaufruf.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Das Rad neu erfinden - Parameter auf Kommandozeile

Beitrag von Xin » Mo Sep 12, 2011 9:46 pm

Panke hat geschrieben:Ja, ich wollte mir D mal angucken. Siehe Beispielaufruf.
Berichte darüber, wie sich D anfühlt. :-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Panke
Beiträge: 70
Registriert: So Nov 14, 2010 10:47 am

Re: Das Rad neu erfinden - Parameter auf Kommandozeile

Beitrag von Panke » Di Sep 13, 2011 7:55 am

D hat ja den Anspruch "C++ done right" zu sein und abgesehen vom bescheuerten Namen
haben sie die letzten zwanzig Jahre Erfahrung bei der Nutzung von Programmiersprachen
auch sichtlich niedergeschlagen. Leider fehlt offensichtlich Manpower, sodass
einige Features immer noch unausgegoren sind.

Die Syntax. Was gefällt mir:
Mit der Syntax wurde aufgeräumt. Arrayliterale werden mit [ ] eingeschlossen.
Funktionpointer werden über die Schlüsselwörter function und delegate definiert,
anstatt der mehr als kruden Syntax aus C++, die ich immer nachschlagen muss.
Template-Argumente werden nicht in < > eingeschlossen, sondern in !( ). Daran
muss man sich gewöhnen, danach ist es aber ebenso gut lesbar. Jedenfalls besser
als das Geplänke > > > in C++03. Bei der Definition von Templates kann man die Templateparameter
bei Klassen und Funktionen einfach hinten anhängen:

class TemplatedClass(T, U)
{
T u;
U t;
}

Es gibt eine foreach-Schleife und man kann eigene Typen so erweitern, dass eine Iteration
mit foreach über sie möglich ist. Genauso wie in C++11 kann man Enumerations so
schreiben, dass sie einen Namensraum eröffnen. Ach ja, und es gibt Slices für eingebaute
Arrays.

Was gefällt mir nicht? Eigentlich nichts. Die Syntax ist gut überlegt. Ich
lese ein bisschen auf der Maillingliste mit und manchmal kommen Vorschläge
für Spracherweiterungen, die dann die C-Syntax an ihre Grenzen bringen würden.
Das einzige, was mich manchmal verwirrt, sind lambda-Funktionen. Die Syntax ist
[function|delegate] ( [params] ) { body }. Also zum Beispiel
function int (int a, int b) { return a + b; }. Aber auch einfach
(int a, int b) { return a + b; }. Wenn sowas alleine steht, ist das in Ordnung. Wenn
das als Parameter eines Funktionsaufrufs vorkommt, haben die ganzen Klammern der
C-Syntax IMO die Eigenschaft den Code ein wenig zu vernebeln.

Eingebaute Datentypen / Grundlegende Sprachfeatures.

Was gefällt mir? Eingebaute dynamische Arrays mit Slicing und (optionalem)
Bound-Checking. Sowas darf heutzutage echt in keiner Sprache fehlen. Außerdem
gibt es Assoziative Arrays als eingebaute Typen - nice. Alle eingebauten Typen haben
wohl definierte Wertebereiche. Das sollte der Portabiblität gut tun.

Unterstützung von Delegates und anonymen Funktionen. Unterstützung von Arrayoperationen.

Code: Alles auswählen

int[] a = [1, 1, 1];
int[] b = [2, 2, 2];
int[] c[] = a[] + b[];
// c ist [3, 3, 3];
Es gibt drei Typen für Chars (char, wchar, dchar), in 8, 16 und 32 Bit. Die stehen für Unicode-Character in UTF-X. Strings sind damit
einfach immutable(char)[] etc. Iteriert man über einen String in char (8 bit), bekommt man keine halben Codepoints geliefert.

Es gibt immutable und const als Typspezifizierer. Const = ich darf nichts ändern (und zwar transitiv) und immutable bedeutet,
dass der Compiler erzwingt, dass niemand eine Variable ändert. Ob das gut oder schlecht ist, kann ich noch nicht beurteilen.

Der größte Potenzial, dass ich in D sehe, ist aber die Fähigkeit Code zur Übersetzungszeit zu generieren und auszuführen und
eine gute Compile-Time-Introspection. Einer hat damit eine Bibliothek für Serializing geschrieben, die fast vollständig
ohne Angaben vom Nutzer auskommt. Einfache eine Datenstruktur reinstecken und der speichert sie und liest sie wieder ein.
Man muss nur eine Zeile extra schreiben, wenn man Subklassen durch Referenzen auf Basisklassen serialisieren will.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Das Rad neu erfinden - Parameter auf Kommandozeile

Beitrag von Xin » Di Sep 13, 2011 9:14 am

Als der Autor mit D anfing, also besser gesagt soweit war, dass er auch davon berichtete, fing ich gerade mit Genesys an. Er war immer weiter als ich - und hat offenbar auch mehr Zeit als ich, aber wir hatten immer ähnliche Ziele und wie ich hier sehe auch ähnliche Entscheidungen getroffen.

Ich habe D nie gelernt, weil ich meine Syntax selbst ausbalancieren wollte.
So sind Arrays sind bei mir allerdings mit {}, int {} array = { 1, 2, 3 };
und [] sind bei mir Listen.

Ansonsten sehe ich sehr viele Ähnlichkeiten. Strings sind bei mir jedoch ein eigener Datentyp.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Panke
Beiträge: 70
Registriert: So Nov 14, 2010 10:47 am

Re: Das Rad neu erfinden - Parameter auf Kommandozeile

Beitrag von Panke » Di Sep 13, 2011 10:22 am

Nach Aussage von Walter stieg die Anzahl der Beiträge von Zweitautoren nach Umstieg auf
git / github um den Faktor 10. Vielleicht etwas um Genesys auf die Sprünge zu helfen.

Was ich in D noch vermisse sind Pythons Generatoren oder Coroutinen und syntaktischer Zucker für Tuple.

Antworten