Rust



  • Hi,

    ich wuerde gerne wissen was die C++ Community von Rust denkt!? Rust geht 1.0 in ca. 4 Wochen... http://www.rust-lang.org/

    Sorry falls das nicht das ganz passende Forum ist.

    MFG
    Miky



  • Dieser Thread wurde von Moderator/in Arcoth aus dem Forum C++ (alle ISO-Standards) in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Miky schrieb:

    ich wuerde gerne wissen was die C++ Community von Rust denkt!?

    Für mich ist Rust keine Alternative zu C++. Ob die genannten Vorteile wirklich so ausschlaggebend sind, wie das Wegwerfen der Erfahrung in C++ und das umlernen bei Syntax/Semantik, muss sich erst noch zeigen. Andere Sprachen wie C# und Java haben auch andere Konzepte als C++ haben aber weit größere Ähnlichkeiten, was den Umstieg von C++ erleichtert. Das heißt nicht das C++ der heilige Gral ist, aber es ist ein Fallstrick den viele machen die sich als Alternative aufbauen wollen - eine Alternative kommt besser an, wenn man auch auf gewohntes setzt.

    Für mich sieht Rust irgendwie so aus wäre ein Basic-Entwickler der Initiator gewesen, der sich mehr an den Bezeichnern als den Fähigkeiten von C und C++ aufgehangen hat.



  • Miky schrieb:

    Hi,

    ich wuerde gerne wissen was die C++ Community von Rust denkt!? Rust geht 1.0 in ca. 4 Wochen... http://www.rust-lang.org/

    Sorry falls das nicht das ganz passende Forum ist.

    MFG
    Miky

    Eintrag noch Justierung des Aggro-Levels editiert.

    Wenn man sich beim offiziellen Rust-Forum nicht registrieren müsste hätte ich spätestens jetzt den gleichen Thread nur für C++ in einem der Rust-Foren aufgemacht.



  • Wer sich mit modernem C++ auseinandergesetzt hat, wird den Sinn von Rust verstehen.



  • Miky schrieb:

    ich wuerde gerne wissen was die C++ Community von Rust denkt!?

    Rust gefällt mir. Ich beschäftige mich damit in meiner Freizeit hin und wieder seit etwa einem Jahr.

    Und danke TyRoXx! Ich dachte schon, es bleibt wieder an mir kleben, zu erwähnen, wie ähnlich sich Rust und "modern C++" konzeptionell sind. Rust hat sich viel von C++ abgeguckt.



  • TyRoXx schrieb:

    Wer sich mit modernem C++ auseinandergesetzt hat, wird den Sinn von Rust verstehen.

    Ich zweifle den Sinn nicht unbedingt an, aber wer unbedingt eine Meinung aus C++ Entwicklersicht haben will, muss sich entsprechende Antworten nun einmal anhören (Und ganz abwegig ist es auch nicht die Aspekte Erfahrung und Gewohnheit zu berücksichtigen - das sind auch Probleme an denen in der Praxis viele gute Sprachansätze im Endeffekt scheitern).



  • Mir gefaellt die Sprache und ich benutze sie so mehr oder weniger seit einem halben Jahr. Man ist sogar erstaunlich produktiv, trotz der Sicherheitsbeschraenkungen.
    Insbesondere die enums sind hilfreich, weil man viele Faelle, in denen man mehrere moegliche Typen hat, nicht mit Vererbung oder verschachtelten if-konstruktionen gut in eine Klasse gekapselt hat, sondern direkt in einem match statement aufloesen kann.



  • Mir gefällt sie auch sehr und steht nach Haskell als nächstes auf meiner TODO Liste zum lernen.



  • Tolles Sprachenkonzept, was einige heftige menschliche Fehler per Compiler verhindert. Auf jeden Fall einen Sprache für alles was in einem Netzwerk agiert und schnell sein muss.

    Manchmal muss man das Alte abbrennen, damit Neues entstehen kann.



  • OverflowKiller schrieb:

    Manchmal muss man das Alte abbrennen, damit Neues entstehen kann.

    Das hat man mir schon vor 30 Jahren erzählt. "ADA, COBOL, FORTRAN sind tot vieleicht noch ein, zwei Jahre".



  • Sind sie ja auch, hat man damals also wohl recht gehabt.



  • Und was ist mit den mio. LOC die heute noch in Finanzbehörden und Banken ihr Unwesen treiben?



  • Hat aber gedauert, ich habe hier noch bis vor zwei Jahren auch mit Fortran arbeiten müssen.



  • Solange es keine IDE gibt, fasse ich Rust auch nicht an.
    Und bei somanchen syntaktischen Konstrukten koennte ich kotzen.



  • Nur dass das nicht missverstanden wird, aber welche Art von Konstrukten meinst du. Möchte jetzt nämlich nicht rust ausprobieren müssen um dahinter zu kommen was du meinen könntest.



  • andreasgeorg schrieb:

    OverflowKiller schrieb:

    Manchmal muss man das Alte abbrennen, damit Neues entstehen kann.

    Das hat man mir schon vor 30 Jahren erzählt. "ADA, COBOL, FORTRAN sind tot vieleicht noch ein, zwei Jahre".

    Habe erst, auf dem Brett meiner Hochschule, eine Studienarbeit zur Entwicklung eines Cobol-Formatters gesehen ;).



  • Der Grund, warum ich Rust noch nicht viel einsetze, hat nix mit den hier genannten Sorgen zu tun. Es liegt einfach daran, dass in der Doku zur Standardbilbiothek noch zu oft "unstable" steht und die Zahl an Bibliotheken anderer Leute noch sehr überschaubar ist. Deswegen ist mein aktuelles Hobby-Projekt in C++, wo ich Boost.ASIO drin verwenden kann.

    Kellerautomat schrieb:

    Und bei somanchen syntaktischen Konstrukten koennte ich kotzen.

    simbad schrieb:

    Nur dass das nicht missverstanden wird, aber welche Art von Konstrukten meinst du. Möchte jetzt nämlich nicht rust ausprobieren müssen um dahinter zu kommen was du meinen könntest.

    Eigentlich ist die Syntax insgesamt harmloser als das, was dir in C++ zugemutet wird. Man gewöhnt sich schnell um. Und vieles lässt sich dann leichter lesen und schreiben.

    Mir fallen aber auch zwei Eigenschaften von Rust ein, die im Vergleich zu C++ zu mehr Code führen oder syntaktisch "komisch" aussehen können. Das erste ist: Rust bietet kein Overloading. Du kannst also nicht schreiben

    fn tcp_connect(sa: SocketAddr) -> io::Result<TcpStream> {
        …
    }
    
    fn tcp_connect(a: IpAddr, port: u16) -> io::Result<TcpStream> {
        tcp_connect(SocketAddr::new(a, port))
    }
    
    fn tcp_connect(sa: &str) -> io::Result<TcpStream> {
        let (host, port) = parse_stuff(sa);
        let ip = hostname_to_ipaddr(host);
        tcp_connect(ip, port)
    }
    

    Was man stattdessen machen kann, sieht in etwa so aus

    trait ToSocketAddr {
        fn to_socket_addr(&self) -> SocketAddr;
    }
    
    impl ToSocketAddr for SocketAddr {
        fn to_socket_addr(&self) -> SocketAddr {
            *self
        }
    }
    
    impl ToSocketAddr for (IpAddr, u16) {
        fn to_socket_addr(&self) -> SocketAddr {
            SocketAddr::new(self.0, self.1)
        }
    }
    
    impl ToSocketAddr for str {
        fn to_socket_addr(&self) -> {
            let (host, port) = parse_stuff(self);
            let ip = hostname_to_ipaddr(host);
            (ip, port).to_socket_addr()
        }
    }
    
    fn tcp_connect<A: ToSocketAddr>(a: &A) -> io::Result<TcpStream> {
        let sa = a.to_socket_addr();
        …
    }
    

    Einerseits ist das nett. Es zwingt dich dazu, tcp_connect nur einmal zu schreiben (don't repeat yourself), so dass nur die Unterschiede quasi ausgelagert werden. Das macht die trait-Implementierungen auch gleichzeitig an anderen Stellen nutzbar (z.B. auch beim Öffnen eines UDP-Sockets) was auch förderlich im Sinne von DRY ist. Eine wichtige Motivation für diesen Ansatz ist die mächtige Typ-Inferenz (Hindley-Milner), die mit Overloading wahrscheinlich nicht so toll interagieren würde. Andererseits brauche ich in diesem Beispiel offensichtlich ohne Overloading mehr Zeilen. Es ist also eine Stelle, wo einem eine "Sauberkeit" quasi aufgewzgunen wird, die ggf zu mehr Zeilen Code führt.

    Und das zweite, was mir da einfällt sind die Lebenszeitparameter, die man manchmal explizit hinschreiben muss. Das ist ja ein Konzept, was C++ nicht kennt. Es ist aber in Rust nötig, um Speichersicherheit ohne Garbage Collection garantieren zu können. Es ist nötig, im Typsystem etwas über Lebenszeiten sagen zu können. Meistens muss man Lebenszeiten nicht explizit benennen:

    struct Person { vorname: String, nachname: String }
    
    fn foo(p: &Person) -> &str { &p.vorname }
    fn bar(p: &Person) -> &str { &p.nachname }
    

    Es funktioniert einfach auf magische Weise und der Compiler kann einem trotzdem garantieren, dass die Referenzen, die foo und bar zurückgeben und sich auf das "Innere" eines Person-Objekts beziehen, immer gültig bleiben (sofern der Compiler das Programm akzeptiert). Wie funktioniert das jetzt? Der Trick ist, dass hier Lebenszeitparameter im Spiel und Teil des Typsystems sind. Wir haben hier ein oft vorkommendes Muster: Die Lebenszeit dessen worauf sich das Ergebnis von foo und bar bezieht, ist dieselbe wie die Lebenszeit der Referenz, die als Argument übergeben wird. Explizit aufgeschrieben heißt das

    fn foo<'a>(p: &'a Person) -> &'a str { &p.vorname }
    fn bar<'a>(p: &'a Person) -> &'a str { &p.nachname }
    

    Es sind also tatsächlich Funktionsfamilien, polymorph über den Lebenszeitparameter 'a. Wenn man von diesem "Eingabe=Ausgabe"-Muster abweicht, muss man auch explizit werden. Beispiel:

    fn min<'a, T: Ord>(x: &'a T, y: &'a T) -> &'a T {
        if x < y {
            x
        } else {
            y
        }
    }
    

    Hier würde 'a vom Compiler als maximale Lebenszeit deduziert, die die Lebenszeit von *x und von *y nicht überschreitet. Der Compiler weiß damit anhand der Signatur (also ohne die Implementierung zu kennen), dass sich die zurückgegebene Referenz nicht länger als das Minimum der Lebenszeit von *x und *y am leben bleiben darf. Das ist vielleicht nicht sofort nachzuvollziehen. Aber Referenztypen sind Kontravariant bzgl des Lebenszeitparameters. Man darf also den Lebenszeitparameter eines Referenzwertes verkleinern, ohne dass dabei was schief gehen kann.

    Weil man hier bei dieser Funktion nicht drum herum kommt, explizit was zu Lebenszeiten zu sagen, ist das natürlich eine Sache, die syntaktisch umständlicher als in C++ aussieht. Aber wir machen das ja auch nicht umsonst!

    HTH,
    kk



  • simbad schrieb:

    Nur dass das nicht missverstanden wird, aber welche Art von Konstrukten meinst du. Möchte jetzt nämlich nicht rust ausprobieren müssen um dahinter zu kommen was du meinen könntest.

    Was mir gerade so einfaellt, was ich an Rust nicht mag:

    • Returns ohne 'return'
    • Implizites const
    • Erzwungene {}
    • Implizites move
    • unions versteckt als enums
    • Pattern matching

    Gibt bestimmt noch einiges mehr.



  • Kellerautomat schrieb:

    • Returns ohne 'return'

    Unwichtiges, syntaktisches Detail, woran man sich schnell gewöhnt.

    Kellerautomat schrieb:

    • Implizites const
    • Erzwungene {}
    • Implizites move

    Das sind eindeutige Vorteile gegenüber C++.

    Kellerautomat schrieb:

    • unions versteckt als enums
    • Pattern matching

    union in C ist etwas anderes als enum in Rust.
    Pattern matching ist die längst überfällige Überführung von switch ins 21. Jahrhundert.

    Kellerautomat schrieb:

    Gibt bestimmt noch einiges mehr.

    Du kennst Rust nicht, also fürchtest du es erst einmal. Ist doch ganz normal.


Anmelden zum Antworten