Die Programmiersprache D



  • Ich finde es nicht gut lesbar wenn ein Funktionsaufruf das Ziel einer Zuweisung sein kann. Es widerspricht auch total dem, was eine Funktion im mathematischen Sinne ursprünglich war.

    Und wenn ich jetzt so einen Frickelcode habe und den Multithreaded machen soll, dann kann es hier ganz leicht passieren, dass ich einen üblen Seiteneffekt einfach übersehe und irrtümlich annehme, der Code sei jetzt threadsafe. Bei max() erwarte ich keine Seiteneffekte aber auch bei jeder anderen Funktion, die an sich eigentlich threadsafe wäre, kann hier was passieren, sobald das array nicht mehr exklusiv von diesem Thread benutzt wird.

    Angesichts der zukünftigen Herausforderungen, die eher einen effektfreien Code nahelegen, ist so ein Programmierstil meiner Meinung nach nicht wünschenswert. Seiteneffekte sollte man nicht verstecken, sondern ganz besonders hervorheben. Das Ergebnis einer Funktion als lvalue zu behandeln versteckt Seiteneffekte und scheint mir eher eine Gelegenheit für tolle l33t-c0d0r zu sein, die damit zeigen können, wie geil kompakt sie alles ausdrücken können.



  • ist doch nur gewohnheitssache. funktionen als lvalue kennt man sonst nicht, deswegen die ablehnung, ne? in C kannste z.b. eine 'max' funktion schreiben, die eine adresse zurückgibt: *max(a,b) *= 1.4;. nur ein '*' vorne dran, sonst das selbe.
    🙂



  • Optimizer schrieb:

    Ich finde es nicht gut lesbar wenn ein Funktionsaufruf das Ziel einer Zuweisung sein kann.

    na ja,

    std::vector<int> v;
    // ...
    v.at(10) = 10;
    //...
    

    ist halt ne Referenz



  • Optimizer schrieb:

    Das Ergebnis einer Funktion als lvalue zu behandeln versteckt Seiteneffekte und scheint mir eher eine Gelegenheit für tolle l33t-c0d0r zu sein, die damit zeigen können, wie geil kompakt sie alles ausdrücken können.

    Eine Kompakte Ausdrucksweise hat nichts mit "l33t-c0d0r" zu tun, sondern mit Lesbarkeit. Ein Beispiel aus einem Quelltext, den ich für eine Übung schreiben musste:

    public void add(X x, int anzahl) {
      Integer i = data.get(x);
      if(i != null)
        anzahl += i;
      data.put(x, anzahl);
    }
    

    vs

    void add(X x, int anzahl) {
      data[x] += anzahl;
    }
    

    Und das ist noch ein simpler Fall. Wenn man Seiteneffekte vermeiden will, nimmt man entweder eine funktionale Sprache oder markiert eben alles als konstant.



  • rüdiger schrieb:

    Optimizer schrieb:

    Das Ergebnis einer Funktion als lvalue zu behandeln versteckt Seiteneffekte und scheint mir eher eine Gelegenheit für tolle l33t-c0d0r zu sein, die damit zeigen können, wie geil kompakt sie alles ausdrücken können.

    Eine Kompakte Ausdrucksweise hat nichts mit "l33t-c0d0r" zu tun, sondern mit Lesbarkeit.

    Wobei diese Aussage auch wieder impliziert, dass kompakter Code lesbar ist. Und das ist so verallgemeinert einfach nur falsch.



  • Tim schrieb:

    rüdiger schrieb:

    Optimizer schrieb:

    Das Ergebnis einer Funktion als lvalue zu behandeln versteckt Seiteneffekte und scheint mir eher eine Gelegenheit für tolle l33t-c0d0r zu sein, die damit zeigen können, wie geil kompakt sie alles ausdrücken können.

    Eine Kompakte Ausdrucksweise hat nichts mit "l33t-c0d0r" zu tun, sondern mit Lesbarkeit.

    Wobei diese Aussage auch wieder impliziert, dass kompakter Code lesbar ist. Und das ist so verallgemeinert einfach nur falsch.

    Lesbar ist es definitiv. Lesbarer nicht unbedingt. Da hast du recht. Richtig formuliert wäre es wohl gewesen "Zu schreiben können, was man meint, hat nichts mit "l33t-c0d0r" zu tun, sondern mit Lesbarkeit."



  • rüdiger schrieb:

    Optimizer schrieb:

    Das Ergebnis einer Funktion als lvalue zu behandeln versteckt Seiteneffekte und scheint mir eher eine Gelegenheit für tolle l33t-c0d0r zu sein, die damit zeigen können, wie geil kompakt sie alles ausdrücken können.

    Eine Kompakte Ausdrucksweise hat nichts mit "l33t-c0d0r" zu tun, sondern mit Lesbarkeit. Ein Beispiel aus einem Quelltext, den ich für eine Übung schreiben musste:

    public void add(X x, int anzahl) {
      Integer i = data.get(x);
      if(i != null)
        anzahl += i;
      data.put(x, anzahl);
    }
    

    vs

    void add(X x, int anzahl) {
      data[x] += anzahl;
    }
    

    Und das ist noch ein simpler Fall. Wenn man Seiteneffekte vermeiden will, nimmt man entweder eine funktionale Sprache oder markiert eben alles als konstant.

    Dein eigentliches Problem ist hier aber ein anderes, nämlich dass du mit Integer-Objekten hantieren musst. Wenn man in Java ein int in ne Collection tun könnte sähe es so aus:

    public void add(X x, int anzahl) {
      data.put(x, data.get(x) + anzahl);
    }
    

    Das ist schön kompakt und man sieht genau wo Seiteneffekte sind. Außerdem hast du in deinem Code-Beispiel beim ersten den Fall behandelt, dass ein Element nicht in der Collection ist, beim zweiten nicht. Ich habe übrigens auch nichts gegen den Index-Operator, aber er sollte nicht unbedingt eine Referenz zurückgeben, sondern einen getter und setter haben.



  • Optimizer schrieb:

    Außerdem hast du in deinem Code-Beispiel beim ersten den Fall behandelt, dass ein Element nicht in der Collection ist, beim zweiten nicht.

    doch.



  • Wieder ein toller Seiteneffekt versteckt. Sehr elitär, ich bin begeistert. (Das ist der Grund, warum der []-op einen getter und setter haben sollte) 🙄



  • Optimizer schrieb:

    Wieder ein toller Seiteneffekt versteckt. Sehr elitär, ich bin begeistert. (Das ist der Grund, warum der []-op einen getter und setter haben sollte) 🙄

    Das Beispiel drückt doch aus, was passieren soll. Die Anzahl von x wird um eine neue Anzahl "anzahl" erhöht. Falls es eben keine (0) x gibt, dann ist der Wert danach "anzahl".

    Das hat nichts mit "Elitär" zu tun, sondern einfach mit Ausdrucksstärke.



  • Falls es eben keine (0) x gibt, dann ist der Wert danach "anzahl"

    Das wird meiner Meinung nach in dieser Zeile überhaupt nicht ausgedrückt. Dass ein Ausdruck map[key] = value unter Umständen einen neuen Key hinzufügt finde ich akzeptabel. Man baut eine Assoziation explizit auf, egal ob es vorher schon so eine gab oder nicht. Aber in deinem Beispiel wird zuerst der Wert gelesen und dieses Lesen fügt einen neuen Wert hinzu. Das drückt dein Code aus meiner Sicht nicht aus.

    Es ist auch eher Zufall, dass in diesem Beispiel so ein Verhalten wünschenswert ist. Was soll denn bei einem String ein sinvoller default-Wert für den Key sein? char* auf 0? Die map verhält sich so, weil sie nicht zwischen lesen und schreiben unterscheidet, nicht weil es irgendwie sinnvoll wäre.



  • Und "ausdrucksstark" macht das eine Programmiersprache natürlich auch nicht. Ich könnte auch die Java-Map beim getten einen neuen Key hinzufügen lassen. Zum Glück haben sie es nicht so gemacht.



  • Optimizer schrieb:

    Falls es eben keine (0) x gibt, dann ist der Wert danach "anzahl"

    Das wird meiner Meinung nach in dieser Zeile überhaupt nicht ausgedrückt.

    Nur weil du viele explizite Angaben erwartest. Aber es ist imho schon sehr logisch, dass man nach Erhöhung der Anzahl um anzahl Elemente eine um anzahl höhere Anzahl von Elementen hat und dass dies auch für den Fall von keinen Elementen vorher gilt.

    Aus dem Grund versucht man ja Programme abstrakt und gekapselt zu modellieren. Die Details sind unwichtig, wichtig ist, dass das erreicht wird, was man möglichst verständlich ausdrückt.

    Optimizer schrieb:

    Was soll denn bei einem String ein sinvoller default-Wert für den Key sein? char* auf 0?

    ein leerer String und bei einem Zeiger ein Nullpointer.



  • Ich wette es sind schon etlich Bugs entstanden weil jemand

    foo = map[key];
    

    geschrieben hat und unerwarteter weise einfach mal ein frisch konstruiertes Objekt zurückgegeben wurde statt dass derjenige einen Fehler erhalten hätte.



  • kartoffelsack schrieb:

    RAII gibts nicht, oder?

    In Wikipedia steht das es RAII in D gibt:
    http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization



  • GPC schrieb:

    Das komplette PDF kann man hier downloaden.

    ...
    So, weiter geht's hier 🙂

    Das PDF Dokument ist nicht mehr verfügbar.



  • PDF schrieb:

    GPC schrieb:

    Das komplette PDF kann man hier downloaden.

    ...
    So, weiter geht's hier 🙂

    Das PDF Dokument ist nicht mehr verfügbar.

    Liegt am Hoster, der da gerade Probleme macht.



  • Cool, echt geil geschrieben :>
    Gibt es eigentlich schon ordentliche IDEs für D?

    Edit: Gibt es eigentlich auch this->-Zeiger und würdest du diese empfehlen, oder nicht? In deiner PDF verwendest du diese ja nicht.

    Gruß



  • theliquidwave schrieb:

    Gibt es eigentlich schon ordentliche IDEs für D?

    Jein 😉 http://stackoverflow.com/questions/50179/an-ide-for-d
    Aber der echte Programmierer nimmt emacs oder vim, ist doch klar 😉

    Edit: Gibt es eigentlich auch this->-Zeiger

    Klar gibt es den.

    und würdest du diese empfehlen, oder nicht?

    Das ist eine Frage des persönlichen Stils und der jeweiligen "Kultur" der Sprache. In C# ist es recht verbreitet, immer this zu benutzen, in C++ weniger.
    Inzwischen verwende ich immer den this-Zeiger, wenn ich auf Instanzvariablen zugreife. Und zwar um sie deutlich von den lokalen/statischen/whatever-Variablen abzuheben. Andere finden das total hässlich und meinen, es müllt den Code zu. Ist Ansichtssache 😉
    Schwachsinn ist allerdings, dass es von der Performance schlechter wäre, wenn man this->member anstatt nur member schreibt.
    Also, such's dir aus 😉



  • Okay. Dankeschön :>
    Ein kleiner Hinweis: auf Seite 16 ist im ersten Satz ein kleiner Tippfehler 😉

    Edit: Deine Arbeit ist echt geil, kann man super zum umsteigen empfehlen. Auf deutsch fand ich nichts besseres und es ist gut zu lesen 😃 </schleimscheiß>

    Edit2: Ich kann diese IDE nur empfehlen! http://d-ide.sourceforge.net/

    Gruß


Log in to reply