Rust-Based, Memory-Safe PNG Decoders "Vastly Outperform" C-Based PNG Libraries

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts
  • TheMightyBuzzard
    Senior Member
    • Sep 2021
    • 416

    #81
    Originally posted by bacteriamanicure View Post

    Well we all know you're excellent at winning those (despite Amnesty's and the pope's objections) so idk what you think you'll lose
    I'm excellent at working on my car too, doesn't mean it's always worth my time.

    Comment

    • TheMightyBuzzard
      Senior Member
      • Sep 2021
      • 416

      #82
      Originally posted by ssokolow View Post

      As someone with 20+ years of Python experience, I'm migrating my projects to Rust because I'm tired of having to reinvent Rust's verbosity even more verbosely (and less reliably) in Python unit tests to push back against "It works! Don't f**k with it!" when the writing ends and the maintaining begins.
      Hahahahahahaha! If you think Rust is going to get rid of or even decrease "It works! Don't f**k with it!", you are sorely mistaken. You're vastly underestimating the laziness of recent graduates who think they should be able to quit learning after four years of college. How do you think we got Rust in the first place? Laziness was the entire motivation for its existence. Thinking it's going to be immune to that same laziness is hilarious.

      Comment

      • ssokolow
        Senior Member
        • Nov 2013
        • 5108

        #83
        Originally posted by TheMightyBuzzard View Post

        Hahahahahahaha! If you think Rust is going to get rid of or even decrease "It works! Don't f**k with it!", you are sorely mistaken. You're vastly underestimating the laziness of recent graduates who think they should be able to quit learning after four years of college. How do you think we got Rust in the first place? Laziness was the entire motivation for its existence. Thinking it's going to be immune to that same laziness is hilarious.
        No, i've got an excellent read on what an idiot "me, two years ago" is and I need to take measures to limit that idiot's ability to make a mess.

        Comment

        • TheMightyBuzzard
          Senior Member
          • Sep 2021
          • 416

          #84
          Originally posted by ssokolow View Post

          That's what you find difficult when C has things like the Clockwise/Spiral Rule?

          It's a trivial function that just layers on a few basic syntaxes C has no equivalent for:
          • It uses async and await to write a fragment of a state machine struct using function syntax.
          • It has the lifetime annotations needed to allow zero-copy deserialization incorporating the input string without risking dangling pointers or leaking the implementation of the function into the API you want to keep stable. (the 'a things, which show up inside the generic parameter lists because, on an abstract level, lifetimes are type-system generics too.)
          • It will do early-return, similar to throwing an exception but as part of the return type signature, if reqwest::get() or response.json() report failure. (the ? operator. Also, you can tell by the :: vs . member-access operators that reqwest::get is an associated function (i.e. class method) while response.json will receive self as its first argument.)
          • It returns a tagged union of either the requested value or an error (the Result<T, E>, which is a de facto standard provided by the standard library).
          • If it returns an error, it will be an exclusive RAII pointer to the heap which (Box) which does dynamic/vtable dispatch (dyn) to some unspecified concrete type which implements the Error interface. (Another de facto standard provided by the standard library.)
          • The type that will be returned on success is generic and may be any type T which implements the Deserialize interface. (Part of the Serde library for serializing and deserializing, which is a de facto standard that's outside the standard library.)
          • response.json() is defined with an overloaded return type and the variant which takes type T will be called (The ::<>, which is known as the turbofish operator and agreed by Rust's developers to be its ugliest construct... but a necessary evil for using familiar-to-C++-developers <> for generic type parameters instead of something like [].)​
          In Plain English, the first four lines are "Define an async function fetch, which is generic over lifetime a and type T. It takes one argument, url, which is a reference (non-nullable pointer) to a string or piece of a string (str) which will remain valid for lifetime a. It returns a Result where the Ok variant is of type T and the Err variant is an RAII smart pointer to something which implements the Error interface. Only types which can implement the Deserialize interface when any references are bounded to lifetime a are valid choices for type T."

          Once you know the syntax, I think the most confusing part for a newcomer of the whole thing is where the heck T's concrete value actually comes from so it knows which variant of response.json to call and the answer is that it's set by Rust's type inference working backwards from what you use fetch's return value for at the call site. Basically, you're looking at that ::<> on response.json from the other side... though the function calling fetch probably won't need ::<> unless it too is just passing T back up to a parent without constraining it to be able to do things with it.

          (Seriously. This is an API which takes a URL and returns a struct deserialized from the resultant JSON with which struct to deserialize to chosen by the type inference information at the call site and, if there isn't enough inference information to unambiguously pick one, you'll have to either use ::<> to specify it explicitly or specify a type on the let for the variable you're assigning it to.)

          The most confusing part for a more experienced programmer is probably why the person who wrote it wanted to bind the lifetime of the returned struct to 'a when I don't see any path for a reference to url to get injected into the returned struct T. (But, thanks to Rust, if there is one and I'm just too low on caffeine to see it, removing the 'a will result in a compile-time error instead of a dangling pointer.)

          You tend to see this kind of verbosity more in the guts of the libraries you depend on than in code you yourself write, because it generally only crops up when you're trying to expose a "just accept anything and do what I mean efficiently" interface where you need to explain how things like type inference should flow from the code calling you to the code you're calling. (Basically, same situation as the horror that is the guts of the C++ STL, but more readable.)

          ...and no, I don't know what this code is from and I've never used it before. I just recognize the types from the standard library and the interfaces from Serde, I know that reqwest is an HTTP client library (not that it was necessary information), and this kind of "do what I mean" API design is commonplace, inspired by how Rust's standard library interfaces enable things like let my_foo: Foo = bar.into();
          I'm glad that you understand all of that. Do you think recent graduates will? Rust started out in large part because of noobs crying about unintuitive C/C++ punctuation and the ability to do a lot of things on one line. Can you see how that's going to be every bit as write-only? Because you need to be able to or you're going to write unmaintainable code.

          Comment

          • Errinwright
            Senior Member
            • Aug 2023
            • 188

            #85
            Originally posted by TheMightyBuzzard View Post

            I'm glad that you understand all of that. Do you think recent graduates will? Rust started out in large part because of noobs crying about unintuitive C/C++ punctuation and the ability to do a lot of things on one line. Can you see how that's going to be every bit as write-only? Because you need to be able to or you're going to write unmaintainable code.
            You genuinely sound like a rambling pseudo-intellectual.

            Comment

            • TheMightyBuzzard
              Senior Member
              • Sep 2021
              • 416

              #86
              Originally posted by Errinwright View Post

              You genuinely sound like a rambling pseudo-intellectual.
              Interesting. Guess the attempt to rise above my current state of Drunken Redneck Indian* overshot a tad. Or maybe you're just a fanboi douchebag and nobody gives a shit what you think. We'll see what the East German judge has to say.

              [Edit]: * Feather not dot.
              Last edited by TheMightyBuzzard; 09 December 2024, 11:03 PM.

              Comment

              • ssokolow
                Senior Member
                • Nov 2013
                • 5108

                #87
                Originally posted by TheMightyBuzzard View Post

                I'm glad that you understand all of that. Do you think recent graduates will?
                I think so. The big difference between C++ and Rust, as far as learnability goes, isn't so much the syntax (Rust was explicitly designed to look like a cleaned-up C++ with a few extra bits and bobs despite being a descendent of a completely different lineage, namely ML via Ocaml), but the amount of work put into making sure you get consistent, sensible errors out of it when you do something that, in C++, would silently invoke undefined behaviour or lead to a segfault. (And, thus, making "learn by doing" a much more sane experience in Rust than in C++.)

                Comment

                • RedEyed
                  Senior Member
                  • Jul 2018
                  • 174

                  #88
                  Originally posted by Steffo View Post

                  Sorry, but this is peace of cake. Did you ever see C++ template meta-programming? I develop in C++ for a living and templates still causes me some headache. Also the undefined behaviour.
                  Templates syntax is peace of cake compared to template related compiler errors!

                  Comment

                  • TheMightyBuzzard
                    Senior Member
                    • Sep 2021
                    • 416

                    #89
                    Originally posted by ssokolow View Post

                    I think so. The big difference between C++ and Rust, as far as learnability goes, isn't so much the syntax (Rust was explicitly designed to look like a cleaned-up C++ with a few extra bits and bobs despite being a descendent of a completely different lineage, namely ML via Ocaml), but the amount of work put into making sure you get consistent, sensible errors out of it when you do something that, in C++, would silently invoke undefined behaviour or lead to a segfault. (And, thus, making "learn by doing" a much more sane experience in Rust than in C++.)
                    Granted there are four or five main points of Rust, depending on who you ask, but readability without having to understand 95 different kinds of arcane syntax was definitely supposed to be one of them. And they've failed horribly on that front. Advanced Rust is no more readable to a noob (yes, recent grads are noobs) than advanced C. You could even argue it's less so except for the extreme asterisk abuse C perpetrates.

                    Sure, the other aspects of Rust have merit but it's not even a tiny bit better than C on producing maintainable code. For any non-basic code, unless you wrote it or have your expert badge, it's effectively every bit as write-only as C.

                    Yes, a very long time Perl fan is actually going off on other languages about being write-only. The irony is not lost on me.

                    Comment

                    • ssokolow
                      Senior Member
                      • Nov 2013
                      • 5108

                      #90
                      Originally posted by TheMightyBuzzard View Post

                      Granted there are four or five main points of Rust, depending on who you ask, but readability without having to understand 95 different kinds of arcane syntax was definitely supposed to be one of them. And they've failed horribly on that front. Advanced Rust is no more readable to a noob (yes, recent grads are noobs) than advanced C. You could even argue it's less so except for the extreme asterisk abuse C perpetrates.
                      I disagree. I remember when I was a Rust noob and a C noob (and I learned C beyond one semester of Hello, World! after Rust) and I found Rust at least as easy, if not easier, to pick up.

                      Plus, one of the important things to keep in mind is that, generally speaking, you don't need to use all of the features. While you ramp up your skills, you can accomplish a lot while leaving most of that hidden inside the seemingly magic API designs that more experienced devs are coming up with. (One of the authors of The Rust Book has said that he only needed to write a macro once.)

                      Hell, that's one of the recurring themes in advice on how to learn/teach Rust. Don't let "make costs explicit" lure you into trying to dive head-first into the deep-end.
                      Last edited by ssokolow; 10 December 2024, 01:50 AM.

                      Comment

                      Working...
                      X