• solrize@lemmy.world
    link
    fedilink
    arrow-up
    0
    ·
    2 days ago

    I had thought the C and Ada zlibs were single threaded. I do some big compression tasks sometimes but haven’t felt the need for a multi-threaded zlib since I just use parallel processes to compress lots of files.

    For an example of Ada safety, integer arithmetic is overflow checked by default. The program raises Constraint_Error on overflow. Rust is checked in debug builds and wraps around (modular arithmetic instead of standard arithmetic) in release builds. Ada also has DBC with static checking using SPARK, and Ada has a much more serious package and module system (that area is under development for Rust though). As another example, Ada has a very rigorous specification (the ARM, or Ada Reference Manual) while Rust is something of amoving target. That again helps verify Ada programs with formal methods.

    Rust doesn’t currently have exceptions, so you have to check error codes pervasively through your program, and that sounds easy to mess up. I don’t know whether Rust’s designers think of this as a shortcoming (fixable later) or a feature.

    I do get the impression that Rust lets you write some things easily that are difficult or impractical in Ada. I don’t know how well Ada handles shared memory concurrency. It has language support for multitasking with tasks communicating through mailboxes, more or less.

    I’ll defer to you about the description of the borrow checker. But, I doubt it’s idiomatic to use standard functional programming techniques in Rust, e.g. shared immutable tree structures for lookups. That usually relies on garbage collection. As you say, Rc and Arc are there in Rust, but as we saw with decades of GIL anguish from Python, it’s imho preferable to do GC for real if that is what you want.

    Disclaimer: I haven’t actually coded anything in Rust so far. I finally got around to reading a book about it recently and I mostly liked what I saw, and it seemed to me to be mostly familiar and reasonably comfortable. I had somehow expect the type system to be much more complicated.

    • eutampieri@feddit.it
      link
      fedilink
      arrow-up
      3
      ·
      1 day ago

      Re: errors Rust Result is an algebraic data type, so an enum with two variants (one is Ok and the other is Err). This means that you cannot use the result without checking it, making impossible to mess up error handling. Well, you can always panic by calling unwrap(), but then you don’t have a program to worry anymore ;)

      • solrize@lemmy.world
        link
        fedilink
        arrow-up
        1
        arrow-down
        1
        ·
        1 day ago

        You also have to check all the time for flags set by signals. Example: your aerodynamic simulation hits a numeric overflow and raises SIGFPE. How do you handle it?

        • badmin@lemm.ee
          link
          fedilink
          arrow-up
          3
          ·
          1 day ago

          Rust supports wrapping, saturating, and checked operations, which allows you to precisely define the behavior you want from your math operations, and avoiding ever hitting an (unchecked) overflow.

          • solrize@lemmy.world
            link
            fedilink
            arrow-up
            1
            arrow-down
            1
            ·
            edit-2
            1 day ago

            I saw something where you can wrap a function around an operation to say how to handle overflow, but that seems like a mistake. Modular (wrapping), saturating (sometimes useful), and checked (standard arithmetic within the machine bounds) are all good, but they should be conveyed in the datatype. Particularly, the default integer datatypes (i32, i64) should be checked. Unchecked arithmetic (including wrapping around when the application is written as if the ints were unbounded) is simply unsafe, like unchecked array subscripts.

            It’s ok if there is an optimization pragma to enable this for performance when necessary. Ada does it the right way, and implementations I know of have such a pragma available for when you want it. Also, while this is a matter of tooling rather than language, Ada currently has better facilities (SPARK) for statically verifying that integer arithmetic in a program doesn’t overflow.

            I’m not trying to bash Rust or get into a Rust vs Ada war, but am noting the differences that I see.

            • badmin@lemm.ee
              link
              fedilink
              arrow-up
              3
              ·
              1 day ago

              Wrapping and Saturating are available as data types in std. Checked can’t be a (useful) data type as-is because it by definition changes the type of the return value of operations (Option<T> instead of T). But you can trivially add a noisy/signalling wrapper yourself if you wish to (basically doing checked ops and unwrapping all results). An example of something offering a noisy interface is a crate named noisy_float.

              • solrize@lemmy.world
                link
                fedilink
                arrow-up
                1
                arrow-down
                2
                ·
                1 day ago

                Checked arithmetic failing should raise an exception like it does in Ada. What happens if you use an out of range array subscript a[n]? Does that always return an option type? Really, these types of errors are rare enough that it’s unfeasible to program defensively around the possibility all the time. But they are frequent enough (especially with malicious input) that we’ve had 50 years of buffer overruns in C, leading to the invention of Rust among other things.

                Wrapping and saturating are for special purposes: wrapping for when you’re explicitly dealing with computer words (as in bit operations or cryptography) and saturating in some media applications and the like. It’s amusing that C in a certain sense is more correct than Rust or Java in this way. Signed arithmetic overflow in C is UB, so the compiler is at least permitted to always check the arithmetic and signal on overflow (use -ftrapv for this). C doesn’t have a way to check unsigned overflow. Things were muddled in the 1970s when C was designed ;).

                I think it would be an improvement to Rust to fix its arithmetic to work like Ada’s.

                • badmin@lemm.ee
                  link
                  fedilink
                  arrow-up
                  4
                  ·
                  23 hours ago

                  What happens if you use an out of range array subscript a[n]? Does that always return an option type?

                  It never returns an option type. This Index interface happens to be actually noisy as implemented for some std types. Although you can implement it however you like for your own data types (including ones just wrapping the std ones). And we have checked access (example) and unchecked access (example) as methods.

                  It’s actually astonishing the lengths you’re taking to NOT learn anything, to the point of just imagining things about Rust that are supposedly done wrong compared to Ada.

                • bitcrafter@programming.dev
                  link
                  fedilink
                  arrow-up
                  2
                  ·
                  24 hours ago

                  What happens if you use an out of range array subscript a[n]? Does that always return an option type?

                  I think that you would be surprised by the amount you would learn if you spent five minutes actually trying to answer your own questions, instead of treating them as proof that you just made a relevant point merely by asking them.