you are viewing a single comment's thread
view the rest of the comments
[–] 11 points 8 months ago (3 children)

One of the reasons i find it so hard to use non-Rust languages is how ugly they typically are by comparison. "fn" instead of "function" is such a great example of saving key presses where they're most needed. And you get very used to seeing compact abbreviations. Idk if that's what you're talking about though.

  • source
  • parent
  • hideshow 6 child comments
  • [–] 8 points 8 months ago (4 children)

    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.

  • source
  • parent
  • hideshow 8 child comments
  • [–] 5 points 8 months ago* (1 child)

    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
  • source
  • parent
  • hideshow 2 child comments
  • [–] 4 points 8 months ago (1 child)

    types in C are pretty weird

    int *a can be read as

    1. *a is a int
    2. since dereferencing is a operator on pointers, a is a pointer to int

    int *a, b is read as

    1. *a and b are int
    2. so a is a pointer to int and b is a int

    bool getofmylawn(Lawn lawn)

    1. getoffmylawn(Lawn lawn) is a bool
    2. since calling is done on functions, getoffmylawn is a function that takes a Lawn and returns a bool

    And then you have function pointers

    bool (*foo(int a))(float b)

    1. (*foo(int a))(float b) is a bool
    2. *foo(int a) is a function from float to bool
    3. foo(int a) is a function pointer from float to bool
    4. foo is a function that takes a int and returns a function pointer from float to bool

    really weird in my opinion.

  • source
  • parent
  • hideshow 2 child comments
  • [–] 5 points 8 months ago (1 child)

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

  • source
  • parent
  • hideshow 2 child comments
  • [–] 6 points 8 months ago (1 child)

    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 ->...

  • source
  • parent
  • hideshow 2 child comments
  • [–] 2 points 8 months ago (1 child)

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

    auto getofmylawn(Lawn lawn) -> Option<Teenager> {
        return lawn.remove();
    }
    
  • source
  • parent
  • hideshow 2 child comments
  • [–] 1 point 8 months ago (1 child)

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

  • source
  • parent
  • hideshow 2 child comments
  • [–] 2 points 8 months ago (1 child)

    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

  • source
  • parent
  • hideshow 2 child comments
  • [–] 2 points 8 months ago (2 children)

    "fn" was just one example. There's also other abbreviations like "pub", "impl", "extern", "mut", "ref", "bool", "u64" And it's true that some of these keywords are only relevant in Rust, however other langues have their own specific keywords, and they tend to be longer. In languages like Java (which is the worst example I can think of), you see things like "private static boolean" as function definition. In c++, you have to type "unsigned long" or even "unsigned long long" to represent "u64" (depending on data model).

  • source
  • parent
  • hideshow 4 child comments
  • [–] 2 points 8 months ago

    I really don't agree with saving keypresses being a useful metric, since auto-completion is a thing and code is read significantly more often than it is written. I am also a staunch opponent of abbreviations being used for variable names.

    But I will say that I don't mind abbreviations in keywords, since well, you need to learn the meaning either way.
    And yeah, I've come to somewhat like them being used for keywords, since it reduces visual noise where it really isn't useful, and it distinguishes keywords from actual code.
    Ultimately, keywords are just syntax where letters were used instead of a symbol. You do read them like a symbol, so if they don't look like a real word, that seems to work quite well for my brain.

  • source
  • parent
  • [–] 1 point 8 months ago* (1 child)

    Yeah, the most beautiful code is where all variables are just letters of the alphabet.

  • source
  • parent
  • hideshow 2 child comments
  • [–] 1 point 8 months ago (1 child)
  • [–] -1 points 8 months ago* (1 child)

    Ooh yeah, overall coding culture is definitely not affected by the preferred nomenclature for identifiers. The person who's habituated to fn over function will absolutely never name their functions in the vein of chkdsk. The two are completely disconnected in the brain of the programmer who read too much K&R in their childhood and was irretrievably traumatized by it for life.

  • source
  • parent
  • hideshow 2 child comments
  • [–] 1 point 8 months ago

    I'd say it's much more influential the names of the identifiers of the standard library.

    A language with function keyword that names it's stdlib functions strstr and strtok will inspire way worse naming than on that has fn keyword with stdlib functions str::contains and str::split.

    We could search for a random crate on crates.io and see what identifiers people actually use, or we could spread misinformation on Lemmy.

  • source
  • parent