Was stört/fehlt euch bei aktuellen Programmiersprachen?



  • Kellerautomat schrieb:

    Naja, wenn es die Konfigurationsdatei oder Datenbankdatei ist, dann ist das schon ein Grund imo. Gerade in solchen Faellen finde ich Exceptions auch extrem praktisch.

    Ich halte die Nutzung von Exceptions für eine Katastrophe.

    Ein Softwareentwickler muss ein kritischer Mensch sein. Das bedeutet in meinem Selbstverständnis, dass er vorhersehen muss, wo das Programm scheitert, um Algorithmen zu formulieren die nicht scheitern.

    Dein Beispiel habe ich bereits implementiert. Findet eins meiner Programme die Konfiguration nicht, legt es eine Standardkonfiguration an. Das ist für mich der Regelfall. if( !Config.Load() ) WriteConfig().

    Es käme mir nie in den Sinn eine Exception zu werfen. Wenn ich beim Start des Programms das Programm konfiguriere und kann das nicht durch das Laden der Konfiguration, wie soll dann irgendeine Funktion im Stacktrace das können?

    Wenn es meine Verantwortung ist, das Programm zu konfigurieren, dann ist meine Funktion auch dafür verantwortlich auf ein "File Not Found" angemessen zu reagieren und das Programm irgendwie startfähig zu machen. Wenn meine Funktion so geschrieben ist, dass sie nicht scheitern kann, dann startet das Programm. Und wenn ich die Funktion irgendwie so schreiben kann, dass sie nicht scheitern kann, dann tue ich das. Aber auf gar keinen Fall, werfe ich eine Exception für etwas belangloses, denn wer immer mich ruft oder denjenigen ruft, der mich gerufen hat, wird darauf spezialisiert sein, das Programm zu konfigurieren.

    Viele Programmierer programmieren aber so, dass wenn der einfachste und erwartete Weg nicht funktioniert, dann bekomme ich eine Exception und die leite ich dann einfach weiter. Man gibt die Verantwortung immer weiter ab. Und irgendwann landet bei main() eine FileNotFound-Exception und main() weiß da auch nix anzufangen, das Programm endet und der User hat die Arschkarte. Für den Entwickler sind Exceptions aber extrem praktisch. Er hat ja eine Exception geworfen und musste sich um nix kümmern.
    Und die Sprache suggeriert, dass das vorbildliches Verhalten ist.

    In meinen Augen sind Exceptions der mit Abstand größte Fail, den Java besitzt bzw. in die gängige Programmierung eingeführt hat.

    Kellerautomat schrieb:

    Ich programmiere noch nicht mal 10 Jahre. Damals hatte ich auch noch keinen Computer :p

    Warum möchtest Du dann eine Programmiersprache schreiben?

    Kellerautomat schrieb:

    Xin schrieb:

    Warum kann man eigentlich nicht von (int 😉 ableiten? ^^

    Weil die Klasse int final ist :p

    Das sehe ich deutlich entspannter.

    Allgemein halte ich nicht viel von 'final'.

    Kellerautomat schrieb:

    gary1195 schrieb:

    2. Referenzen dürfen nicht null sein, außer es wird explizit erlaubt (wie zB bei Vala)

    Das ist bereits der Fall:

    void f(Foo? foo) // Nullable
    

    Bei Klassen geht das auch sehr schön mit

    void f( Foo * foo )
    

    Das ist eine Referenz, die Null sein darf.

    Im Gegensatz zu (Foo?) muss man aber nicht die Information mitführen, ob wie bei (int?) 0 0 oder Null bedeutet. Das ganze macht also nur Sinn, wenn Null ein valider Wert wäre, der sich von Null unterscheidet. Und wenn man über den vorherigen Satz nachdenken muss, um ihn zu verstehen, sollte man sowas im Quelltext vielleicht expliziter ausdrücken.

    Kellerautomat schrieb:

    let m1 := new HashMap!<string, int> // Leere Map
    

    Wofür steht das '!'?

    Gratulation für die Abkehr von '=' für die Zuweisung.

    Wie lange programmierst Du und was hast Du so programmiert?



  • Eigene Programmiersprache? Im Moment sehe ich nur zusammengeklaute Dinge, die sich in den bekannten Sprachen auf die ein oder andere realisieren lassen.

    Gratulation für die Abkehr von '=' für die Zuweisung.

    Ja sehr fortschrittlich anders und ueberhaupt ...

    Jeder computerspielende Depp will sein MMORPG programmieren, wird hier im Forum aber im optimalen Fall nur muede belaechelt, bestenfalls mit dem Verweis erstmal programmieren zu lernen.

    Hier aktuell eine Programmiersprache, die C++, C#, .... alle vereint und super toll ist. Mein Rat: Etwas naeher an der Realitaet bleiben und Grundlagen aufbauen. Viele Probleme sind in der Vergangenheit bereits geloest worden.

    Der Rest hat nichts mehr mit Programmiersprachen an sich zu tun:

    Standardkonfiguration

    Die gibt es nicht immer. Auch kann die Konfiguration von einem ... aeh ... externen Konfigurationsprogramm kommen.

    Programm irgendwie startfähig zu machen

    Ich moechte kein Steuerungprogramm fuer einen Laser startfaehig machen, wenn die Konfigurations fehlt.



  • knivil schrieb:

    Eigene Programmiersprache? Im Moment sehe ich nur zusammengeklaute Dinge, die sich in den bekannten Sprachen auf die ein oder andere realisieren lassen.

    Leute, die nichts anderes zu tun haben, außer kontraproduktiven Mist von sich zu geben, gehören auch nicht zu meiner Zielgruppe.

    knivil schrieb:

    Gratulation für die Abkehr von '=' für die Zuweisung.

    Ja sehr fortschrittlich anders und ueberhaupt ...

    Schön, dass du ohne zu wissen, wovon du sprichst, deine Meinung kundtust.
    := heißt übrigens Initialisierung, = ist eine Zuweisung.

    Den Rest ignorier ich mal.



  • Bevor du weiter mit Beleidigungen um dich wirfst ... komm wieder wenn du was vorzuweisen hast. Viel Glueck bei deinem MMORPG.

    Schön, dass du ohne zu wissen, wovon du sprichst, deine Meinung kundtust.

    Du weisst es doch selbst nicht.



  • Xin schrieb:

    Ich halte die Nutzung von Exceptions für eine Katastrophe.

    Ein Softwareentwickler muss ein kritischer Mensch sein. Das bedeutet in meinem Selbstverständnis, dass er vorhersehen muss, wo das Programm scheitert, um Algorithmen zu formulieren die nicht scheitern.

    Dein Beispiel habe ich bereits implementiert. Findet eins meiner Programme die Konfiguration nicht, legt es eine Standardkonfiguration an. Das ist für mich der Regelfall. if( !Config.Load() ) WriteConfig().

    Es käme mir nie in den Sinn eine Exception zu werfen. Wenn ich beim Start des Programms das Programm konfiguriere und kann das nicht durch das Laden der Konfiguration, wie soll dann irgendeine Funktion im Stacktrace das können?

    Wenn es meine Verantwortung ist, das Programm zu konfigurieren, dann ist meine Funktion auch dafür verantwortlich auf ein "File Not Found" angemessen zu reagieren und das Programm irgendwie startfähig zu machen. Wenn meine Funktion so geschrieben ist, dass sie nicht scheitern kann, dann startet das Programm. Und wenn ich die Funktion irgendwie so schreiben kann, dass sie nicht scheitern kann, dann tue ich das. Aber auf gar keinen Fall, werfe ich eine Exception für etwas belangloses, denn wer immer mich ruft oder denjenigen ruft, der mich gerufen hat, wird darauf spezialisiert sein, das Programm zu konfigurieren.

    Viele Programmierer programmieren aber so, dass wenn der einfachste und erwartete Weg nicht funktioniert, dann bekomme ich eine Exception und die leite ich dann einfach weiter. Man gibt die Verantwortung immer weiter ab. Und irgendwann landet bei main() eine FileNotFound-Exception und main() weiß da auch nix anzufangen, das Programm endet und der User hat die Arschkarte. Für den Entwickler sind Exceptions aber extrem praktisch. Er hat ja eine Exception geworfen und musste sich um nix kümmern.
    Und die Sprache suggeriert, dass das vorbildliches Verhalten ist.

    In meinen Augen sind Exceptions der mit Abstand größte Fail, den Java besitzt bzw. in die gängige Programmierung eingeführt hat.

    Gut, mein Beispiel war zugegebenermaßen blöd gewählt.
    Nach deiner Argumentation ist das Problem also, dass Exceptions einfach weiergegeben werden? Wären dann nicht checked Exceptions von Java die Lösung?!

    Xin schrieb:

    Kellerautomat schrieb:

    Ich programmiere noch nicht mal 10 Jahre. Damals hatte ich auch noch keinen Computer :p

    Warum möchtest Du dann eine Programmiersprache schreiben?

    Weil ich denke, dass ich ein paar gute Ideen habe und aktuelle Sprachen alle irgendwelche Problme haben.

    Xin schrieb:

    Kellerautomat schrieb:

    ]

    Xin schrieb:

    Warum kann man eigentlich nicht von (int 😉 ableiten? ^^

    Weil die Klasse int final ist :p

    Das sehe ich deutlich entspannter.

    Allgemein halte ich nicht viel von 'final'.

    final ist gut als Optimierungsmöglichkeit, daher sind bei mir alle Klassen und Methoden per default final.

    Xin schrieb:

    Das ist eine Referenz, die Null sein darf.

    Im Gegensatz zu (Foo?) muss man aber nicht die Information mitführen, ob wie bei (int?) 0 0 oder Null bedeutet. Das ganze macht also nur Sinn, wenn Null ein valider Wert wäre, der sich von Null unterscheidet. Und wenn man über den vorherigen Satz nachdenken muss, um ihn zu verstehen, sollte man sowas im Quelltext vielleicht expliziter ausdrücken.

    T? nimmt alle Möglichen Werte von T sowie den Wert null auf. Was ist daran schwer?

    Xin schrieb:

    Kellerautomat schrieb:

    let m1 := new HashMap!<string, int> // Leere Map
    

    Wofür steht das '!'?

    Dient dazu, um Mehrdeutigkeiten in der Grammatik aufzulösen.

    Xin schrieb:

    Gratulation für die Abkehr von '=' für die Zuweisung.

    Wie schon mal gesagt: ":=" heißt Initialisierung, "=" ist eine Zuweisung.
    Das hat insbesondere Voteile in Konstruktoren: Man kann die Initialisierung im Funktionskörper durchführen und braucht keine Initialisierungsliste mehr. Außerdem ist die Initialisierungsreihenfolge egal.

    Xin schrieb:

    Wie lange programmierst Du und was hast Du so programmiert?

    Ich hab im Alter von 11 Jahren angefangen, C++ zu lernen.
    Was hab ich gemacht? Eine VM geschrieben in C++, ein paar IRC-Bots in C++ und Java, diverse Minecraft-Server Plugins. Microsoft Sharepoint Plugins in C#. Websites in PHP, Greasemonkey Scripte in JS.

    Nichts großes also, aber dafür viele kleinere Sachen. 😉



  • knivil schrieb:

    Eigene Programmiersprache? Im Moment sehe ich nur zusammengeklaute Dinge, die sich in den bekannten Sprachen auf die ein oder andere realisieren lassen.

    Ich habe vor knapp 10 Jahren eine ähnliche Umfrage gemacht, aber nicht in einem Forum, sondern ich schrieb eine eigene Website dafür, ähnlich surveymonkey. Aber neben fragen ähnlich 'Auf einer Skala von 1 bis 10..." hatte ich auch reichlich Textfelder, wo ich die Leute einfach mal schreiben ließ. Das machen kaum Umfragen, weil man die Ergebnisse nicht automatisiert in ein Excel-Diagramm packen kann. Wissenschaftlich also zu aufwendig, ergo wertlos. Ich sehe mich eher als Praktiker: Für mich sind das interessanten Felder.
    Ich erhielt rund 400 von einander unabhängige Antworten. Die würde kellerautomat vermutlich genauso interessieren, wie mein Aktenordner. ^^

    Die wichtigste Erkenntnis daraus, möchte ich aber durchaus teilen: Während Programmieranfänger, Ingenieure, Mathematiker, Projektleiter, Wirtschaftler, die eben nicht als Informatiker programmierten sich über fast alles beschwerten, fielen ITler nicht nur mit einer Ideenarmut auf ("Da habe ich mir noch nie Gedanken drüber gemacht."), sondern vorrangig damit, dass jeder Versuch etwas zu verändern nicht gewünscht ist: "Zeitverschwendung", "Man kann mit den existieren den Sprachen schon alles machen".
    Ich fand es sehr erstaunlich, wie sehr professionelle Entwickler Wert darauf legen, dass sich ihr Werkzeug nicht verändert. Es ist ja nicht so, dass eine neue Sprache ihnen ihre derzeitige Sprache verbieten würde, es wäre ja nur ein zusätzliches Angebot.

    Jede Programmiersprache "klaut", denn am Schluss kommen doch nur Assembler-Befehle heraus. Man macht nur einige Details anders. Es gibt nur wenige Baustellen, wo man Dinge "neu" machen kann - oder eher - bekannte Dinge fortführen, weiterentwickeln, übertragen kann.

    Es wird keine "neue" Programmiersprache geben. Ich behaute auch nie, dass ich eine "neue" Sprache entwickle, ich behaupte nur, eine "eigene" Sprache entwickle und mich dabei auf andere Dinge konzentriere als andere Sprachen. Eigene Erfahrungen verwerte, auf die in diesem Forum in der Regel ablehnend reagiert wird. Aber aus der Erfahrung heraus, würde ich auch keinen Informatiker ernsthaft mehr fragen, wie er sich sein Haupt-Werkzeug vorstellt, wenn er sich darüber keine Gedanken macht.

    knivil schrieb:

    Gratulation für die Abkehr von '=' für die Zuweisung.

    Ja sehr fortschrittlich anders und ueberhaupt ...

    Im Gegenteil, es ist rückschrittlich. Jede moderne Programmiersprache benutzt für die Zuweisung den '=' Operator. Die Zuweisung per ':=' findet sich eher im Bereich Algol 60, bzw. davon abgeleitet in Pascal und Delphi. Alles mehr oder weniger tote Sprachen.

    Aber die Richtung stimmt. Wer die Zukunft sucht, muss dahin gehen, wo der Java-Hype begann und jedes kreative Denken eliminierte. '=' als Zuweisung ist man gewohnt, darum rüttelt an sowas niemand. Wenn man aber fortschreiten möchte, muss man das gewohnte Umfeld verlassen. Was ich aus dem ':=' herauslese ist nicht, dass er den Doppelpunkt (wieder) dazu setzt, sondern dass er sich nicht durch das Umfeld einengen lässt und sich von ablehnenden Reaktionen, wie der deinigen, die auch eher die Regel als die Ausnahme sein wird, beeinflussen lässt und dazu ist ihm nur zu gratulieren. Indem er sich der Forderung seines Umfeldes widersetzt, alles beim Alten zu lassen, ermöglicht er sich und seinen Ideen Fortschritt.

    Wenn er anfängt, etwas zu implementieren, wird man ihm sagen, dass er das alleine nie schaffen kann. Das habe ich auch schon oft genug gehört, den Spruch in der Signatur kommt daher.

    knivil schrieb:

    Hier aktuell eine Programmiersprache, die C++, C#, .... alle vereint und super toll ist. Mein Rat: Etwas naeher an der Realitaet bleiben und Grundlagen aufbauen. Viele Probleme sind in der Vergangenheit bereits geloest worden.

    Warum programmierst Du denn? Viele Programme sind in der Vergangenheit schon geschrieben worden. Wer braucht da das, was Du schreibst?

    Wenn kellerautomat soweit ist, eine Sprache wie C zu übersetzen, wird sehr, sehr viel mehr Grundlagen über Datenverarbeitung mehr gelernt haben, als die meisten Informatiker. Und er wird viel genauer verstehen, was eine Sprache eigentlich tut, wenn man sie programmiert - weil er nicht nur die Grundlagen gelernt hat, sondern sie wörtwörtlich begriffen hat.

    Ich habe auch keine Ahnung, ob meine Sprache jemals fertig wird. Aber es macht Spaß. Genauso wie es anderen Spaß macht, das 100. Tetris zu programmieren. Ich habe immernoch Spaß am Programmieren, obwohl ich 40 Stunden pro Woche als Software-Entwickler arbeite. Auch etwas, was die meisten Software-Entwickler verlieren: Den Spaß an der Sache.
    Ich programmiere seit 1989. Der Reiz wäre sicherlich längst weg, wenn ich nur Fließbandarbeiten und nur die Lösungen der Vergangenheit abschreiben würde.
    Also glaube ich nicht, dass ich was falsch mache. ^^



  • Kellerautomat schrieb:

    Xin schrieb:

    Ich halte die Nutzung von Exceptions für eine Katastrophe.

    Ein Softwareentwickler muss ein kritischer Mensch sein. Das bedeutet in meinem Selbstverständnis, dass er vorhersehen muss, wo das Programm scheitert, um Algorithmen zu formulieren die nicht scheitern.

    Dein Beispiel habe ich bereits implementiert. Findet eins meiner Programme die Konfiguration nicht, legt es eine Standardkonfiguration an. Das ist für mich der Regelfall. if( !Config.Load() ) WriteConfig().

    Es käme mir nie in den Sinn eine Exception zu werfen. Wenn ich beim Start des Programms das Programm konfiguriere und kann das nicht durch das Laden der Konfiguration, wie soll dann irgendeine Funktion im Stacktrace das können?

    Gut, mein Beispiel war zugegebenermaßen blöd gewählt.
    Nach deiner Argumentation ist das Problem also, dass Exceptions einfach weiergegeben werden? Wären dann nicht checked Exceptions von Java die Lösung?!

    Nein, das wäre eine Symptombehandlung.

    Für 4 Zeilen C++ Code, die nicht fehlschlagen konnten, brauchte ich 2 Seiten Java-Quelltext, weil ich diszipliniert jede Exception abarbeiten musste, die per 'throws' vorgegeben waren.

    Alleine die Trennung von Fehlerauftritt und Fehlerbehandlung halte ich für falsch - das muss zusammenbleiben.
    Das Springen über die Funktionshierarchie hinaus, ist eine Katastrophe.

    Vielliecht hast Du mal was von INTERCAL gehört. Das ist eine Programmiersprache aus den 70ern. Bekannt wurde sie für das "COME FROM"-Statement, ein inverses Goto. Erreicht das Programm das Label, das bei COME FROM angegeben ist, verzweigt es an die Stelle, wo das COME FROM im Quelltext steht.

    Etwa so:

    printf( "1\n" );
    Label:
    
      printf( "2\n" );
    
      come from Label;
    
      printf( "3\n" );
    

    Ausgabe:
    1
    3

    INTERCAL hatte nur einen Zweck: Die Programmierung so umständlich und schlecht wie möglich zu machen. Eine reine Demonstration, wie man es nicht machen soll.

    Und jetzt ersetze mal "COME FROM" mit "catch" und vor das Label schreibst Du "throw"... 😉

    Kellerautomat schrieb:

    Xin schrieb:

    Kellerautomat schrieb:

    Ich programmiere noch nicht mal 10 Jahre. Damals hatte ich auch noch keinen Computer :p

    Warum möchtest Du dann eine Programmiersprache schreiben?

    Weil ich denke, dass ich ein paar gute Ideen habe und aktuelle Sprachen alle irgendwelche Problme haben.

    Und reichen die Ideen, um den Aufwand zu rechtfertigen?

    Kellerautomat schrieb:

    final ist gut als Optimierungsmöglichkeit, daher sind bei mir alle Klassen und Methoden per default final.

    Spricht ja nicht gegen Optimierung, solange man das final zurücknehmen kann. ^^

    Kellerautomat schrieb:

    Xin schrieb:

    Das ist eine Referenz, die Null sein darf.

    Im Gegensatz zu (Foo?) muss man aber nicht die Information mitführen, ob wie bei (int?) 0 0 oder Null bedeutet. Das ganze macht also nur Sinn, wenn Null ein valider Wert wäre, der sich von Null unterscheidet. Und wenn man über den vorherigen Satz nachdenken muss, um ihn zu verstehen, sollte man sowas im Quelltext vielleicht expliziter ausdrücken.

    T? nimmt alle Möglichen Werte von T sowie den Wert null auf. Was ist daran schwer?

    Nichts. Aber wo braucht man es, außer bei Primitiven?

    Ist das ein Konstrukt wert?
    Ist das ein ? wert?
    Wenn Du viele Ideen hast, wird Dir auffallen, dass Kurzzeichen-Operatoren eher Mangelware sind.

    Kellerautomat schrieb:

    Xin schrieb:

    let m1 := new HashMap!<string, int> // Leere Map
    

    Wofür steht das '!'?

    Dient dazu, um Mehrdeutigkeiten in der Grammatik aufzulösen.[/quote]
    Mehrdeutigkeiten? Welche könnte das sein?
    Es ist doch Deine Grammatik und da sollte die Sache doch möglichst eindeutig sein?

    Kellerautomat schrieb:

    Xin schrieb:

    Gratulation für die Abkehr von '=' für die Zuweisung.

    Wie schon mal gesagt: ":=" heißt Initialisierung, "=" ist eine Zuweisung.

    Oh... schade. ^^

    Kellerautomat schrieb:

    Das hat insbesondere Voteile in Konstruktoren: Man kann die Initialisierung im Funktionskörper durchführen und braucht keine Initialisierungsliste mehr. Außerdem ist die Initialisierungsreihenfolge egal.

    let f1 := Foo(1);
    let f2 := Foo(2);
    
    f1 := f2;
    

    Was bedeutet das?

    Kellerautomat schrieb:

    Xin schrieb:

    Wie lange programmierst Du und was hast Du so programmiert?

    Ich hab im Alter von 11 Jahren angefangen, C++ zu lernen.

    Interessanter Zeitpunkt, dann verstehst Du Programmiersprachen vermutlich anders als die meisten hier.

    Fang mal an und halt mich auf dem Laufenden. Interessiert mich. Wenn Du Fragen hast, auf unten genanntem Forum lese ich alle Boards und bin unter UsernameHier at proggen.org zu erreichen, hier lese eigentlich nur "Beruf und Ausbildung" und ansonsten nur wenn ich Zeit habe und/oder zufällig was Interessantes mitbekomme.



  • Xin schrieb:

    Alleine die Trennung von Fehlerauftritt und Fehlerbehandlung halte ich für falsch - das muss zusammenbleiben.

    Damit stehst du aber beei vielen Fehlern alleine da. Die meisten Fehler sind nicht vor ort korrigierbar.



  • PS: @Xin, du erzaehlst gern von dir ... aber das Thema bist nicht du und ich will auch nicht ueber dich reden. Deswegen schweige ich zu deinem Beitrag.



  • otze schrieb:

    Xin schrieb:

    Alleine die Trennung von Fehlerauftritt und Fehlerbehandlung halte ich für falsch - das muss zusammenbleiben.

    Damit stehst du aber beei vielen Fehlern alleine da. Die meisten Fehler sind nicht vor ort korrigierbar.

    Das ist vielleicht eine Frage der Perspektive, bzw. nach der Antwort auf die Frage "Was ist ein Fehler"? Was ist Wunsch, was ist Erwartung?

    Möchte ich die Konfiguration laden, so ist mein Wunsch, dass ich die Datei finde und einlesen kann. Meine Erwartung ist aber, dass mein Wunsch in er Erfüllung gehen kann - aber eben nicht muss. Wenn ich die Datei nicht finde, ist jetzt der optimale Zeitpunkt, darauf zu reagieren, denn ich weiß an dieser Stelle ohne weitere Nachfrage, welches Detail hier eigentlich nicht wunschgemäß verlaufen ist. Entsprechend kann ich das Detail häufig schon korrigieren und den eigentlichen Algorithmus weiterlaufen lassen.

    Zu einem Fehler, also dass der Algorithmus nicht weiter weiß, sollte es also gar nicht kommen.

    Kommt es trotzdem zu einem besonderen Fehler, zum Beispiel, dass die bereits geöffnete Datei nicht mehr gelesen werden kann, weil jemand den USB-Stick gezogen hat, akzeptiere ich ausnahmsweise eine Ausnahme.

    knivil schrieb:

    PS: @Xin, du erzaehlst gern von dir ... aber das Thema bist nicht du und ich will auch nicht ueber dich reden. Deswegen schweige ich zu deinem Beitrag.

    Ein PS kommt nach dem Beitrag, ein PS ohne einen Beitrag ist sinnfrei.

    Schweigen ist nicht mit "Ich poste, dass ich schweige" zu realisieren, zumal Du auch hier nur Destruktives beizutragen hast. Du möchtest nochmal in meine Richtung treten, das wird auch nicht zu "schweigen", wenn Du schreibst, dass Du schweigen würdest.

    Sollte der Threadstarter an meinen "Erzählungen" nicht interessiert sein, so darf er mir das gerne sagen.

    Wenn Du daran nicht interessiert bist, das Thema ist nicht für Dich.
    Sofern Du nichts Konstruktives beizutragen hast, schweige bitte aktiv.



  • Xin schrieb:

    Nein, das wäre eine Symptombehandlung.

    Für 4 Zeilen C++ Code, die nicht fehlschlagen konnten, brauchte ich 2 Seiten Java-Quelltext, weil ich diszipliniert jede Exception abarbeiten musste, die per 'throws' vorgegeben waren.

    Alleine die Trennung von Fehlerauftritt und Fehlerbehandlung halte ich für falsch - das muss zusammenbleiben.
    Das Springen über die Funktionshierarchie hinaus, ist eine Katastrophe.

    Vielliecht hast Du mal was von INTERCAL gehört. Das ist eine Programmiersprache aus den 70ern. Bekannt wurde sie für das "COME FROM"-Statement, ein inverses Goto. Erreicht das Programm das Label, das bei COME FROM angegeben ist, verzweigt es an die Stelle, wo das COME FROM im Quelltext steht.

    Etwa so:

    printf( "1\n" );
    Label:
    
      printf( "2\n" );
    
      come from Label;
    
      printf( "3\n" );
    

    Ausgabe:
    1
    3

    INTERCAL hatte nur einen Zweck: Die Programmierung so umständlich und schlecht wie möglich zu machen. Eine reine Demonstration, wie man es nicht machen soll.

    Und jetzt ersetze mal "COME FROM" mit "catch" und vor das Label schreibst Du "throw"... 😉

    Und wie behandelst du dann Fehler, bei denen am Zeitpunkt des Auftretens nicht bekannt ist, wie sie behandelt werden sollen? Gerade das macht Exceptions doch so praktisch.

    Xin schrieb:

    Kellerautomat schrieb:

    Xin schrieb:

    Kellerautomat schrieb:

    Ich programmiere noch nicht mal 10 Jahre. Damals hatte ich auch noch keinen Computer :p

    Warum möchtest Du dann eine Programmiersprache schreiben?

    Weil ich denke, dass ich ein paar gute Ideen habe und aktuelle Sprachen alle irgendwelche Problme haben.

    Und reichen die Ideen, um den Aufwand zu rechtfertigen?

    Ja.

    Xin schrieb:

    Kellerautomat schrieb:

    final ist gut als Optimierungsmöglichkeit, daher sind bei mir alle Klassen und Methoden per default final.

    Spricht ja nicht gegen Optimierung, solange man das final zurücknehmen kann. ^^

    Man muss es eben explizit sagen. Selbst wenn eine Funktion in der Basklasse überschreibbar ist, wird sie in einer abgeleiteten Klasse automatisch wieder final.

    Xin schrieb:

    Kellerautomat schrieb:

    Xin schrieb:

    Das ist eine Referenz, die Null sein darf.

    Im Gegensatz zu (Foo?) muss man aber nicht die Information mitführen, ob wie bei (int?) 0 0 oder Null bedeutet. Das ganze macht also nur Sinn, wenn Null ein valider Wert wäre, der sich von Null unterscheidet. Und wenn man über den vorherigen Satz nachdenken muss, um ihn zu verstehen, sollte man sowas im Quelltext vielleicht expliziter ausdrücken.

    T? nimmt alle Möglichen Werte von T sowie den Wert null auf. Was ist daran schwer?

    Nichts. Aber wo braucht man es, außer bei Primitiven?

    Ist das ein Konstrukt wert?
    Ist das ein ? wert?
    Wenn Du viele Ideen hast, wird Dir auffallen, dass Kurzzeichen-Operatoren eher Mangelware sind.

    Ein Zeiger kann viel mehr als ein Nullable. Er kann auch einfach irgendwohin zeigen, das kann ein Nullable nicht. Ausserdem haben Nullable spezielle Operatoren. Das Feature des Nullable liegt darin, dass die Semantik beschränkt wird auf das Wichtige.

    Xin schrieb:

    Kellerautomat schrieb:

    Xin schrieb:

    Kellerautomat schrieb:

    let m1 := new HashMap!<string, int> // Leere Map
    

    Wofür steht das '!'?

    Dient dazu, um Mehrdeutigkeiten in der Grammatik aufzulösen.

    Mehrdeutigkeiten? Welche könnte das sein?
    Es ist doch Deine Grammatik und da sollte die Sache doch möglichst eindeutig sein?

    Die können entstehen, wenn der Benutzer eigene Operatoren definieren kann. Ich bin mir aber auch bei der template-Syntax noch nicht sicher.

    Xin schrieb:

    Kellerautomat schrieb:

    Xin schrieb:

    Gratulation für die Abkehr von '=' für die Zuweisung.

    Wie schon mal gesagt: ":=" heißt Initialisierung, "=" ist eine Zuweisung.

    Oh... schade. ^^

    Was willst du damit sagen? 😕

    Xin schrieb:

    Kellerautomat schrieb:

    Das hat insbesondere Voteile in Konstruktoren: Man kann die Initialisierung im Funktionskörper durchführen und braucht keine Initialisierungsliste mehr. Außerdem ist die Initialisierungsreihenfolge egal.

    let f1 := Foo(1);
    let f2 := Foo(2);
    
    f1 := f2;
    

    Was bedeutet das?

    Nichts, das ist ungültiger Code. In Codezeile 3 hättest du = verwenden müssen.
    Die Semikola sind übrigens optional, ein \n in der Datei reicht.

    Xin schrieb:

    Kellerautomat schrieb:

    Xin schrieb:

    Wie lange programmierst Du und was hast Du so programmiert?

    Ich hab im Alter von 11 Jahren angefangen, C++ zu lernen.

    Interessanter Zeitpunkt, dann verstehst Du Programmiersprachen vermutlich anders als die meisten hier.

    Fang mal an und halt mich auf dem Laufenden. Interessiert mich. Wenn Du Fragen hast, auf unten genanntem Forum lese ich alle Boards und bin unter UsernameHier at proggen.org zu erreichen, hier lese eigentlich nur "Beruf und Ausbildung" und ansonsten nur wenn ich Zeit habe und/oder zufällig was Interessantes mitbekomme.

    Mich würde interessieren, was du mit "anders" meinst 😉

    Wenn ich heute Abend Zuhause bin, reistriere ich mich mal dort. Könnte auch einen Thread zu meiner Sprache aufmachen.

    Edit: Bist du eigtl. evtl. irgendwo im IRC unterwegs?



  • Ich hätte gerne ein C++ mit weniger Sonderregeln und dafür eine höhere Regularität.

    Man muss hier und da immer noch zuviel schreiben, gerade wenn man generischen Code schreiben will und man die ganzen Typen, mit denen man zu tun hat, gar nicht kennt. Mehr Deduktion bitte.

    Ich hätte gern implicit statt explicit .

    Ich hätte gerne ein C++ ohne diesen ganzen Initialisierungs-Blödsinn (default, value, zero, direct, copy, direct-list, copy-list, ...).

    Ich hätte gerne ein C++ wo all die Sachen die in C++11 deprecated sind, rausgeflogen sind, damit auch Anfänger nicht mehr die Dreierregel verletzen können, auch wenn sie davon noch nie gehört haben.

    Das, was C++ leistet finde ich schon ganz nett. Aber die Form, in der man es aufschreiben muss ist irgendwie doof.

    Ich wünschte, der ganze Metaprogrammierungskram wäre leichter. Da muss man ja echt krasse Verreknungen machen teilweise. Otto Normalo wird sich daran nicht stören, aber einen Entwickler generischer Bibliotheken nervt das sicher.

    Ich hätte gerne einen Debug-Modus, der mir so etwas wie einen weak_ptr für einen unique_ptr geben kann, der dann automatisch 0 wird, wenn der unique_ptr das Ding löscht und dann bei Dereferenzierung in so einem Zustand den Debugger aktiviert. Nur zwecks Fehlererkennung. Im Release-Mode könnte das ja wieder ein raw-Pointer sein. So könnte man noch dangling-pointer-Probleme in Verbindung mit unique_ptr früher erkennen.

    Ich hätte gern ein vernünftiges Modul-System, ohne diesen ganzen Header-Krampf. Dann kann man vielleicht auch wieder eine using-Direktive verwenden, weil der using namespace-Kram dann ja nicht in die Schnittstellen-Datei exportiert werden muss.

    Ich hätte gerne concepts light2.

    Ich hätte gerne ein C++, was sich flotter kompilieren lässt. Vielleicht hilft ein ordentliches Modul-System da schon aus.

    Ich hätte gern eine bessere Tuple-Unterstützung. Zum Beispiel so etwas wie folgende syntaktische Abkürzung

    tuple<int,int&,double&> get_stuff();
    
    int main() {
      {a,b,const& c} = get_stuff();
      cout << a;
      cout << b;
      cout << c;
    }
    

    für so etwas:

    tuple<int,int&,double&> get_stuff();
    
    int main() {
      tuple<int,int,const double&> abc = get_stuff();
      cout << std::get<0>(abc);
      cout << std::get<1>(abc);
      cout << std::get<2>(abc);
    }
    

    Ich hätte gern ein ordentliches Range-System (das kann man noch auf Bibliotheksbasis machen), so dass man z.b. so Dinge schreiben kann wie

    iunt main()
    {
      vector<double> foo = get_other_stuff();
      for ({index,&value} : indexed(foo)) {
        cout << index << " --> " << value << endl;
      }
    }
    

    wobei es dann noch viele schöne andere "Range-Adapter" gibt...

    😃



  • ich haette es auch gerne effizienter vom tippen her.

    1. wenn schon accessor als sauberer stil angepriesen sind, dann sollte man sie effizienter definieren koennen bis man mehr als den reinen access braucht z.b.

    class foo
    {
    int m_Bar:bar;
    };
    
    ...
    foo F;
    F.bar(1);
    return F.bar();
    

    ich wuerde gerne typesafe enum operatoren haben, wenn es sowas wie

    enum EFlags;
    {
     EF_01= 1<<0,
     EF_10= 1<<1,
     EF_11= 3,//EF_01|EF_10
    };
    

    gibt, sollte man auch sowas schreiben koennen

    EFlags Flags(){return EF_01|EF_10;}
    

    zZ hat man ugly type cast falls man das moechte oder man muss auf einen generischen typ umsteigen und verliert damit die 'safety' was gerade bei funktionsueberladen schiefgehen kann.

    Flux(EF_10);
    Flux(EF_01|EF_10);
    

    was bauzeit angeht, das ist aber mehr ein compiler wunsch, eine differenzierung zwischen verschiedenen header/inl etc. dateien. es sollte rein deklarierende dateien geben die nicht includen duerfen und was man braucht kommt von der translation unit oder wird per forward declaration bestimmt. es sollte auch 'inl' geben die auch nicht includen duerfen, sie haben nur definitionen der deklarationen die dann (wie der name sagt) inlined werden.
    schon mit diesen beiden 'features' koennte man das meiste an header include hell loswerden.
    c++ builds sind sehr davon abhaengig wie man programmiert, ich habe zuhause wirklich grosse projekte die ich aufgeraeumt habe und die compile time ging von ein paar minuten auf <10s runter. (ja, natuerlich hab ich multi-prozessor builds eingebaut und unity/ueber files, aber sehr viel ging aufs konto von includes).

    im allgemeinen wuerde ich mir wuenschen mehr features zu haben die schnelleres coden erlauben, ich fuehle mich irgendwie staendig ineffizient. (weil mein kopf 10mal mehr generiert als ich hinklatschen kann).



  • @Xin: Natuerlich ist das Kritik. Ich verstehe sie nicht als destruktiv. Wenn du sie nicht hoeren moechtest, dann unterhaltet euch doch privat, weil das Forum oeffentlich ist.



  • Kellerautomat schrieb:

    Xin schrieb:

    INTERCAL hatte nur einen Zweck: Die Programmierung so umständlich und schlecht wie möglich zu machen. Eine reine Demonstration, wie man es nicht machen soll.

    Und jetzt ersetze mal "COME FROM" mit "catch" und vor das Label schreibst Du "throw"... 😉

    Und wie behandelst du dann Fehler, bei denen am Zeitpunkt des Auftretens nicht bekannt ist, wie sie behandelt werden sollen? Gerade das macht Exceptions doch so praktisch.

    Vereinfach ausgedrückt: "false".

    Wenn die rufende Funktion kein Ergebnis bekommt, kann sie das vielleicht reparieren.

    Wenn ich aber eine Exception schmeiße und 5 Funktionen über mir kommt eine "Division by zero" Exception an, dann kann die damit auch nix mehr anfangen. Ich gehe schön brav Step by Step den Stacktrace hoch. Ein Schritt nach dem anderen, niemals zwei auf einmal. Jeder darf mal kurz überlegen, ob die Rückgabe der Funktion für ihn existenziell wichtig ist, oder ob man da noch was machen kann.

    Kellerautomat schrieb:

    Xin schrieb:

    Und reichen die Ideen, um den Aufwand zu rechtfertigen?

    Ja.

    Always listen to experts.
    They tell you what can't be done and why.

    Then do it.

    Wenn Du das das erste Mal geschafft hast, siehe Signatur. 😉

    Kellerautomat schrieb:

    Xin schrieb:

    Kellerautomat schrieb:

    final ist gut als Optimierungsmöglichkeit, daher sind bei mir alle Klassen und Methoden per default final.

    Spricht ja nicht gegen Optimierung, solange man das final zurücknehmen kann. ^^

    Man muss es eben explizit sagen. Selbst wenn eine Funktion in der Basklasse überschreibbar ist, wird sie in einer abgeleiteten Klasse automatisch wieder final.

    Dass man Ableitungen verbietet, mag ich nicht.

    Dass man die Überschreibbarkeit für Ableitungen fordern muss... darüber muss ich nachdenken, ob ich das für eine gute Idee halte.

    Kellerautomat schrieb:

    Xin schrieb:

    Kellerautomat schrieb:

    Xin schrieb:

    Das ist eine Referenz, die Null sein darf.

    Im Gegensatz zu (Foo?) muss man aber nicht die Information mitführen, ob wie bei (int?) 0 0 oder Null bedeutet. Das ganze macht also nur Sinn, wenn Null ein valider Wert wäre, der sich von Null unterscheidet. Und wenn man über den vorherigen Satz nachdenken muss, um ihn zu verstehen, sollte man sowas im Quelltext vielleicht expliziter ausdrücken.

    T? nimmt alle Möglichen Werte von T sowie den Wert null auf. Was ist daran schwer?

    Nichts. Aber wo braucht man es, außer bei Primitiven?

    Ist das ein Konstrukt wert?
    Ist das ein ? wert?
    Wenn Du viele Ideen hast, wird Dir auffallen, dass Kurzzeichen-Operatoren eher Mangelware sind.

    Ein Zeiger kann viel mehr als ein Nullable. Er kann auch einfach irgendwohin zeigen, das kann ein Nullable nicht. Ausserdem haben Nullable spezielle Operatoren. Das Feature des Nullable liegt darin, dass die Semantik beschränkt wird auf das Wichtige.

    Ein Nullable kann Null sein oder nicht. Ein (int*?) könnte entsprechend Null sein oder nullptr oder irgendwo hin zeigen. Das ist nicht semantisch gleichwertig zu (int *), aber ob es ein Mehrwert ist?
    Bei int, float und enum ist es unbestritten ein Mehrwert - nur halt die Frage, ob das die Implementierung rechtfertigt und damit die Notwendigkeit das Konstrukt zu erlernen.

    Kellerautomat schrieb:

    Xin schrieb:

    Kellerautomat schrieb:

    Xin schrieb:

    Gratulation für die Abkehr von '=' für die Zuweisung.

    Wie schon mal gesagt: ":=" heißt Initialisierung, "=" ist eine Zuweisung.

    Oh... schade. ^^

    Was willst du damit sagen? 😕

    Dass ich es begrüßt hätte, wenn der '='-Operator nicht für als Kopier-Operator missbraucht wird, der von Anfängern dann mit dem '=='-Operator verwechselt wird.

    Kellerautomat schrieb:

    Xin schrieb:

    Kellerautomat schrieb:

    Das hat insbesondere Voteile in Konstruktoren: Man kann die Initialisierung im Funktionskörper durchführen und braucht keine Initialisierungsliste mehr. Außerdem ist die Initialisierungsreihenfolge egal.

    let f1 := Foo(1);
    let f2 := Foo(2);
    
    f1 := f2;
    

    Was bedeutet das?

    Nichts, das ist ungültiger Code. In Codezeile 3 hättest du = verwenden müssen.

    Warum unterscheidest Du dann im Quelltext zwischen Zuweisung und Initialisierung?
    Warum muss der Code ungültig sein?

    Kellerautomat schrieb:

    Xin schrieb:

    Kellerautomat schrieb:

    Xin schrieb:

    Wie lange programmierst Du und was hast Du so programmiert?

    Ich hab im Alter von 11 Jahren angefangen, C++ zu lernen.

    Interessanter Zeitpunkt, dann verstehst Du Programmiersprachen vermutlich anders als die meisten hier.

    Fang mal an und halt mich auf dem Laufenden. Interessiert mich. Wenn Du Fragen hast, auf unten genanntem Forum lese ich alle Boards und bin unter UsernameHier at proggen.org zu erreichen, hier lese eigentlich nur "Beruf und Ausbildung" und ansonsten nur wenn ich Zeit habe und/oder zufällig was Interessantes mitbekomme.

    Mich würde interessieren, was du mit "anders" meinst 😉

    Ich habe mit 9 Jahren angefangen zu programmieren, mit etwa 13 habe ich angefangen Assembler zu programmieren. C und C++ waren damals auf den Computern, die ich mir leisten konnte, nicht verfügbar.

    "Digital Natives", so nennt man das heute so schön, sind bei Programmiersprachen doch eher selten.

    Ich vermute, wer eine Programmiersprache nicht als "Zweitsprache" erlernt, geht damit anders um, als jemand, der eine Sprache eher anhand ihrer Regeln gelernt hat.

    Kellerautomat schrieb:

    Edit: Bist du eigtl. evtl. irgendwo im IRC unterwegs?

    Nicht mehr.

    Entweder stehst Du gerade vor mir oder ich habe keine Zeit für Live-Kommunikation. 😉

    @krümelkacker: Schöne Punkte. 🙂

    knivil schrieb:

    @Xin: Natuerlich ist das Kritik. Ich verstehe sie nicht als destruktiv. Wenn du sie nicht hoeren moechtest, dann unterhaltet euch doch privat, weil das Forum oeffentlich ist.

    Lieber knivil, richte Dir doch bitte ein Forum ein, in dem nur öffentlich besprochen wird, was Dich persönlich interessiert. Ich verspreche, ich komme dann auch nicht vorbei. Wenn Du konstruktive Beiträge zum Thema hast, bitte. Wenn Du Kritik an mir hast, dann ist dieser Thread nicht der passende Bereich. Schreib mir privat, schreib an den Board-Moderator oder akzeptiere, dass dieses Thema nunmal nicht für Dich interessant ist und schweige, wie du es ja eigentlich von selbst aus tun wolltest.



  • Xin schrieb:

    Kellerautomat schrieb:

    Und wie behandelst du dann Fehler, bei denen am Zeitpunkt des Auftretens nicht bekannt ist, wie sie behandelt werden sollen? Gerade das macht Exceptions doch so praktisch.

    Vereinfach ausgedrückt: "false".

    Fehlerbehandlung über Rückgabewerte funktioniert, allerdings braucht man dazu Sum-Typen, sonst hat man ein Problem, wenn die Funktion noch einen normalen Rückgabewert hat. Und damit man dann nicht ständig die Rückgabewerte prüfen muss, braucht man auch noch Monaden bzw. Unterstützung für monadische Strukturen.

    Tatsächlich sind insbesondere Sum-Typen in Verbindung mit Pattern Matching eines der Dinge, die mir bei vielen Sprachen, auch C++, fehlen.



  • krümelkacker schrieb:

    Ich hätte gern implicit statt explicit .

    Über Konvertierungen habe ich noch nicht nachgedacht. Aber du hast Recht, ich fände implicit auch besser.

    krümelkacker schrieb:

    Ich hätte gerne ein C++ ohne diesen ganzen Initialisierungs-Blödsinn (default, value, zero, direct, copy, direct-list, copy-list, ...).

    Hehe. Bei mir gibt es nur 2 Arten von Initialisierung: void-Initialisierung und "normale" Initialisierung. Eine void-Initialisierung entspricht einer uninitialisierten Variable. Wer das möchte, muss es explizit hinschreiben:

    let int x := void // Uninitialisierter int
    

    Und dann eben "normale" Initialisierung, wie ich schon vorher gezeigt habe.

    krümelkacker schrieb:

    Ich wünschte, der ganze Metaprogrammierungskram wäre leichter. Da muss man ja echt krasse Verreknungen machen teilweise. Otto Normalo wird sich daran nicht stören, aber einen Entwickler generischer Bibliotheken nervt das sicher.

    Idealerweise kann man Code sowohl zur Lauzeit, als auch zur Compilezeit ausführen, ohne Änderungen. Details habe ich mir aber noch nicht überlegt.

    krümelkacker schrieb:

    Ich hätte gerne einen Debug-Modus, der mir so etwas wie einen weak_ptr für einen unique_ptr geben kann, der dann automatisch 0 wird, wenn der unique_ptr das Ding löscht und dann bei Dereferenzierung in so einem Zustand den Debugger aktiviert. Nur zwecks Fehlererkennung. Im Release-Mode könnte das ja wieder ein raw-Pointer sein. So könnte man noch dangling-pointer-Probleme in Verbindung mit unique_ptr früher erkennen.

    Das ist wohl ein Library-Feature bzw Teil der Implementierung.

    krümelkacker schrieb:

    Ich hätte gern ein vernünftiges Modul-System, ohne diesen ganzen Header-Krampf. Dann kann man vielleicht auch wieder eine using-Direktive verwenden, weil der using namespace-Kram dann ja nicht in die Schnittstellen-Datei exportiert werden muss.

    Wird wohl bei mir ähnlich wie in Java aussehen. Die Zuteilung Klassenname <-> Dateiname wird es aber nicht geben, da ein Modul keine Klassen beinhalten muss. Weiters wird man importierte Symbole "umbenennen" können, falls mehrere importierte Module ein gleichnamiges Symbol definieren.

    module MyModule
    
    // komplettes Modul importieren
    import CoolModule CM
    import OtherCoolModule OCM
    
    // oder auch
    from CoolModule CM import f
    from OtherCoolModule OCM import f
    
    void f()
    {
        CM.f();
        OCM.f();
    }
    

    krümelkacker schrieb:

    Ich hätte gerne concepts light2.

    Damit meinst du was?

    krümelkacker schrieb:

    Ich hätte gern eine bessere Tuple-Unterstützung. Zum Beispiel so etwas wie folgende syntaktische Abkürzung

    tuple<int,int&,double&> get_stuff();
    
    int main() {
      {a,b,const& c} = get_stuff();
      cout << a;
      cout << b;
      cout << c;
    }
    

    für so etwas:

    tuple<int,int&,double&> get_stuff();
    
    int main() {
      tuple<int,int,const double&> abc = get_stuff();
      cout << std::get<0>(abc);
      cout << std::get<1>(abc);
      cout << std::get<2>(abc);
    }
    

    Etwas ähnliches gibt es schon: std::tie.
    Mit Pattern Matching liesse sich das in meiner Sprache so schreiben:

    let { a, b, c } := get_stuff()
    

    Allerdings weiss ich noch nicht, ob ich Referenzen auf Primitive einführe. const wird es aber definitiv geben.

    krümelkacker schrieb:

    Ich hätte gern ein ordentliches Range-System (das kann man noch auf Bibliotheksbasis machen), so dass man z.b. so Dinge schreiben kann wie

    iunt main()
    {
      vector<double> foo = get_other_stuff();
      for ({index,&value} : indexed(foo)) {
        cout << index << " --> " << value << endl;
      }
    }
    

    wobei es dann noch viele schöne andere "Range-Adapter" gibt...

    Was die stdlib angeht, habe ich zwar Ranges geplant, aber noch keine Details. Vermutich würde ich Indizierung in die Sprache einbauen:

    let foo := get_other_stuff()
    
    foreach(i, value in foo)
        printfln("% --> %", i, value)
    

    rapso schrieb:

    1. wenn schon accessor als sauberer stil angepriesen sind, dann sollte man sie effizienter definieren koennen bis man mehr als den reinen access braucht z.b.

    class foo
    {
    int m_Bar:bar;
    };
    
    ...
    foo F;
    F.bar(1);
    return F.bar();
    

    Ich finde eher, es sollte in Richtung C# Properties gehen.

    rapso schrieb:

    ich wuerde gerne typesafe enum operatoren haben, wenn es sowas wie

    enum EFlags;
    {
     EF_01= 1<<0,
     EF_10= 1<<1,
     EF_11= 3,//EF_01|EF_10
    };
    

    gibt, sollte man auch sowas schreiben koennen

    EFlags Flags(){return EF_01|EF_10;}
    

    zZ hat man ugly type cast falls man das moechte oder man muss auf einen generischen typ umsteigen und verliert damit die 'safety' was gerade bei funktionsueberladen schiefgehen kann.

    Flux(EF_10);
    Flux(EF_01|EF_10);
    

    Sowas nenne ich "flags enum":

    enum flags X
    {
        foo,
        bar,
        baz = foo | bar
    }
    

    rapso schrieb:

    im allgemeinen wuerde ich mir wuenschen mehr features zu haben die schnelleres coden erlauben, ich fuehle mich irgendwie staendig ineffizient. (weil mein kopf 10mal mehr generiert als ich hinklatschen kann).

    Wenn du konkrete Vorschläge hast, bin ich immer dankbar 😉

    @Xin + ipsec: Ich habe leider im Moment wenig Zeit, werde auf eure Posts später eingehen. Habe sie aber nicht vergessen.



  • Kellerautomat schrieb:

    Was die stdlib angeht, habe ich zwar Ranges geplant, aber noch keine Details. Vermutich würde ich Indizierung in die Sprache einbauen:

    let foo := get_other_stuff()
    
    foreach(i, value in foo)
        printfln("% --> %", i, value)
    

    Genau das ist mein Problem mit aktuellen Programmiersprachen: Sie haben viel zu viele Sprachfeatures. Eine Sprache muss schlank und erweiterbar sein und Features sollen von der Library implementiert werden, wenn möglich.

    Es gibt sehr viele Features, die ganz nett wären. Und das schlimmste, was man machen kann, ist diese als Special Case in die Sprachdefinition einbauen.

    Gerade das Indexproblem wäre einfach zu lösen: foo gibt einen Typ zurück, der sich in ein 1-Tupel (Nur Wert) oder 2-Tupel (Index+Wert) umwandeln lässt. Wenn foo eine Map wäre, wären das 1-Tupel (Key-Value-Pair), 2-Tupel (Index + Key-Value-Pair) und 3-Tupel (Index + Key + Value).

    Viele der Features, die du genannt hast, lassen sich verallgemeinern und zusammenmergen.

    Beispiel:

    let int x := void
    

    Wird nur sehr selten gebraucht und wenn, dann lässt sich das durch einen uninitialized<int> lösen, der intern aligned_storage<int> (was sowieso benötigt wird) verwendet. Gewinn: Einfachere Sprache, weniger Fehlerquellen.



  • Kellerautomat schrieb:

    Eine void-Initialisierung entspricht einer uninitialisierten Variable. Wer das möchte, muss es explizit hinschreiben:

    let int x := void // Uninitialisierter int
    

    Und dann eben "normale" Initialisierung, wie ich schon vorher gezeigt habe.

    Interessante Schreibweise... bei mir heißt es "uninitialized int", wobei das uninitialized nur bei Klassen interessant ist, deren Konstruktor ich noch nicht rufen möchte. Es ist nicht verpflichtend und bei int sinnfrei.
    Aber die Idee mit void hat was... nicht, dass mir das void gefiel, aber die zwangsweise "Initialisierung" gefällt mir.

    Kellerautomat schrieb:

    Idealerweise kann man Code sowohl zur Lauzeit, als auch zur Compilezeit ausführen, ohne Änderungen. Details habe ich mir aber noch nicht überlegt.

    AST-Interpreter.

    Ist lustig, wenn man Goto implementiert. 😃

    Kellerautomat schrieb:

    krümelkacker schrieb:

    Ich hätte gerne einen Debug-Modus, der mir so etwas wie einen weak_ptr für einen unique_ptr geben kann, der dann automatisch 0 wird, wenn der unique_ptr das Ding löscht und dann bei Dereferenzierung in so einem Zustand den Debugger aktiviert. Nur zwecks Fehlererkennung. Im Release-Mode könnte das ja wieder ein raw-Pointer sein. So könnte man noch dangling-pointer-Probleme in Verbindung mit unique_ptr früher erkennen.

    Das ist wohl ein Library-Feature bzw Teil der Implementierung.

    Bei unique_ptr vielliecht.

    Kellerautomat schrieb:

    Allerdings weiss ich noch nicht, ob ich Referenzen auf Primitive einführe. const wird es aber definitiv geben.

    Beschäftige Dich mit der Frage, inwieweit Du Primitive einführst.

    Kellerautomat schrieb:

    Sowas nenne ich "flags enum":

    enum flags X
    {
        foo,
        bar,
        baz = foo | bar
    }
    

    Flags sind kein Enums. Darum heißt es bei mir nur flags. Der Rest ist identisch.

    Wenn ich meine Sprache startklar habe, sollten wir uns mal auf eine kühles Getränk treffen und uns über die Syntax austauschen. Mir scheint, wir werden reichlich gemeinsamkeiten finden.

    typique schrieb:

    Genau das ist mein Problem mit aktuellen Programmiersprachen: Sie haben viel zu viele Sprachfeatures. Eine Sprache muss schlank und erweiterbar sein und Features sollen von der Library implementiert werden, wenn möglich.

    Da habe ich genau den entgegengesetzten Ansatz. Ich möchte alles, was regelmäßig gebraucht wird, in der Sprache leicht zugänglich haben.

    Das bedeutet auch, dass sich Sprachen weiterentwickeln, weil die üblichen Ansprüche sich ändern und Sprachen für alte Ansprüche irgendwann unpraktisch werden, um neue zu erfüllen.

    Seien wir ehrlich: C++ ist eine tolle Sprache, sie erfüllt viele Ansprüche, aber im Alltag ist sie unpraktisch, weswegen Sprachen wie C#, Python und sogar PHP erfolgreich wurden. Die Sprachen wurden doch nicht erfolgreich, weil sie besser als C++ sind, sondern nur, weil sie im Alltag praktischer sind.

    typique schrieb:

    Viele der Features, die du genannt hast, lassen sich verallgemeinern und zusammenmergen.

    Beispiel:

    let int x := void
    

    Wird nur sehr selten gebraucht und wenn, dann lässt sich das durch einen uninitialized<int> lösen, der intern aligned_storage<int> (was sowieso benötigt wird) verwendet. Gewinn: Einfachere Sprache, weniger Fehlerquellen.

    Ich finde kellerautomats Syntax lesbarer. Das Problem halte ich für alltäglich.



  • Xin schrieb:

    Kellerautomat schrieb:

    Und wie behandelst du dann Fehler, bei denen am Zeitpunkt des Auftretens nicht bekannt ist, wie sie behandelt werden sollen? Gerade das macht Exceptions doch so praktisch.

    Vereinfach ausgedrückt: "false".

    Wenn die rufende Funktion kein Ergebnis bekommt, kann sie das vielleicht reparieren.

    Wenn ich aber eine Exception schmeiße und 5 Funktionen über mir kommt eine "Division by zero" Exception an, dann kann die damit auch nix mehr anfangen. Ich gehe schön brav Step by Step den Stacktrace hoch. Ein Schritt nach dem anderen, niemals zwei auf einmal. Jeder darf mal kurz überlegen, ob die Rückgabe der Funktion für ihn existenziell wichtig ist, oder ob man da noch was machen kann.

    Dann hast du aber in jeder Funktion Fehlerbehandlungscode, was nicht nur ineffizient, sondern auch unglaublich mühsam ist. Was machst du eigentlich in Konstruktoren?

    Xin schrieb:

    Kellerautomat schrieb:

    Man muss es eben explizit sagen. Selbst wenn eine Funktion in der Basklasse überschreibbar ist, wird sie in einer abgeleiteten Klasse automatisch wieder final.

    Dass man Ableitungen verbietet, mag ich nicht.

    Dass man die Überschreibbarkeit für Ableitungen fordern muss... darüber muss ich nachdenken, ob ich das für eine gute Idee halte.

    Und, hast du dir schon eine Meinung gebildet? 🙂

    Xin schrieb:

    Ein Nullable kann Null sein oder nicht. Ein (int*?) könnte entsprechend Null sein oder nullptr oder irgendwo hin zeigen. Das ist nicht semantisch gleichwertig zu (int *), aber ob es ein Mehrwert ist?
    Bei int, float und enum ist es unbestritten ein Mehrwert - nur halt die Frage, ob das die Implementierung rechtfertigt und damit die Notwendigkeit das Konstrukt zu erlernen.

    Ich bin mir nicht sicher, ob ich einen int*? überhaupt erlauben soll, ähnlich wie man in C++ keinen Zeiger auf eine Referenz erzeugen kann.
    Ich halte die Semantik zumindest für fragwürdig und denke, dass das Verwirrung stiften würde.

    Bei Klassentypen ist Nullable auch nützlich: Man erkennt am Interface, ob eine Funktion null entgegennehmen/zurückgeben kann, oder nicht. Das füehrt dazu, dass viel null-Behandlungscode wegfällt, der in z.B. Java üblich ist.

    Xin schrieb:

    Kellerautomat schrieb:

    Was willst du damit sagen? 😕

    Dass ich es begrüßt hätte, wenn der '='-Operator nicht für als Kopier-Operator missbraucht wird, der von Anfängern dann mit dem '=='-Operator verwechselt wird.

    Ich kann das Problem selbst nicht nachvollziehen. Ich glaube, der Fehler ist mir vor ungefähr einem Monat zum ersten mal passiert, und das war um vier Uhr morgens. Wie wärs mit Haskell-Syntax?

    x <- 42
    

    Xin schrieb:

    Kellerautomat schrieb:

    Nichts, das ist ungültiger Code. In Codezeile 3 hättest du = verwenden müssen.

    Warum unterscheidest Du dann im Quelltext zwischen Zuweisung und Initialisierung?
    Warum muss der Code ungültig sein?

    Weil ich finde, dass eine Unterscheidung zwischen Initialisierung und Zuweisung den Code klarer macht. Und wenn, dann verwende ich sie konsistent.
    Den Vorteil in Konstruktoren habe ich ja schon genannt:

    type Foo
    {
    	// Memberfunktionen und Kon/Destruktoren sind per default public
    	Foo(int x, float y, string z)
    	{
    		// beliebiger Code, member noch nicht initialisiert
    		let temp := someComputation()
    
    		println(.x) // x noch nicht initialisiert, daher read nicht erlaubt --> compiletime error
    
    		.x := x / temp // initialisierung
    
    		if y % 2 == 0
    			.y := 42 // nope, bedingte Initialisierung nicht erlaubt --> compiletime error
    
    		// read von .x okay, wurde initialisiert
    		.z := .x ~ z
    	}
    
    	// Member sind private per default
    	int x
    	float y
    	string z
    }
    

    (Syntax noch nicht fertig)
    Auf Member greift man explizit mit der .member Syntax zu. In C++ gibt es verschiedene Namenskonventionen, etwa m_Member oder member_. Damit baue ich das fest in die Sprache ein.


Anmelden zum Antworten