• Lucy :3@feddit.org
    link
    fedilink
    arrow-up
    7
    arrow-down
    3
    ·
    12 hours ago

    Rust:

    fn getofmylawn(lawn: Lawn) -> bool {
        lawn.remove()
    }
    

    C:

    bool getofmylawn(Lawn lawn) {
        return lawn.remove();
    }
    

    With Rust you safe 1 char, and gain needing to skip a whole line to see what type something is.

    • fruitcantfly@programming.dev
      link
      fedilink
      arrow-up
      2
      ·
      edit-2
      2 hours ago

      With Rust you safe 1 char, and gain needing to skip a whole line to see what type something is.

      Honestly, the Rust way of doing things feels much more natural to me.

      You can read it as

      1. Define a function,
      2. with the name getoffmylawn,
      3. that takes a Lawn argument named lawn,
      4. and returns a bool

      Whereas the C function is read as

      1. Do something with a bool? Could be a variable, could be a function, could be a forward declaration of a function,
      2. whatever it is, it has the name getoffmylawn,
      3. there’s a (, so all options are still on the table,
      4. ok, that’ a function, since it takes a Lawn argument named lawn, that returns a bool
    • chunes@lemmy.world
      link
      fedilink
      arrow-up
      4
      ·
      9 hours ago

      So that’s why people like C-style return types. That actually makes a lot of sense. I do too now.

      • Ephera@lemmy.ml
        link
        fedilink
        English
        arrow-up
        6
        ·
        8 hours ago

        To be honest, I think, they both have their place. In Rust, you typically wouldn’t return just a bool, but rather the element that you removed, so like this:

        fn getofmylawn(lawn: Lawn) -> Option<Teenager> {
            lawn.remove()
        }
        

        And then with such a more complex return-type, C-style means that you can’t see the function name right away:

        Option<Teenager> getofmylawn(Lawn lawn) {
            return lawn.remove();
        }
        

        I also really don’t think, it’s a big deal to move your eyes to the ->

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

          Amusingly, modern C++ allows you to copy the rust signature nearly 1:1:

          auto getofmylawn(Lawn lawn) -> Option<Teenager> {
              return lawn.remove();
          }
          
          • Ephera@lemmy.ml
            link
            fedilink
            English
            arrow-up
            1
            ·
            1 hour ago

            Huh, did that emerge out of unrelated design decisions or did they just figure
            why not both?

            • fruitcantfly@programming.dev
              link
              fedilink
              arrow-up
              2
              ·
              56 minutes ago

              I believe that it is useful in a few places. cppreference.com mentions templates as one case:

              Trailing return type, useful if the return type depends on argument names, such as template<class T, class U> auto add(T t, U u) -> decltype(t + u); or is complicated, such as in auto fpif(int)->int(*)(int)

              The syntax also matches that of lambdas, though I’m not sure that adding another way of specifying regular functions actually makes the language more consistent, since most code still uses the old style.

              Additionally, the scope of the return type matches the function meaning that you can do

              auto my_class::my_function() -> iterator { /* code */ }
              

              instead of

              my_class::iterator my_class::my_function() { /* code */ }
              

              which is kinda nice