1. 36
  1.  

  2. 7

    BTW, C is simple, but I still can’t write something more than Hello World (or GTK window with single button) in it. Unlike C, I think if you know Rust, you already know how to write programs in it.

    1. 5

      I feel like I know Rust well enough but when I try to do some things they can take more time than I expected due to borrow issues cropping up, and I am comfortable with unmanaged ownership generally. Most of this comes down to using the language on a periodic enough basis that it is not quite second-nature.

      As a result I’m reluctant to use it unless I know exactly what I want to write in it, mostly because my time is limited and I’m worried I’ll get stuck. At the same time I really like the resulting code. It’s just a matter of shifting perceptions and expectations for what one gets done in a given coding session.

      1. 1

        Doesn’t Rust have optional, reference counting? A few people deep in the borrow-checker vs full GC language threads on HN drop in saying you can do checked references in Rust. If so, that means times where borrow-checker is hard dont necessarily imply ditching Rust for that project: could just ditch the borrow-checker until better at it or not at all if it’s throwaway project. Then, recommendation becomes use Rust with borrow-checker for full benefits but reference counting for most.

        Also, these plus veterans’ solutions might form a corpus of sorts for helping people figure out how to get things through borrow checking. The posts on linked lists come to mind. Another benefit is testing alternative schemes for checking pointers to see over time what usability improvements are available.

        1. 13

          Rust has a ref-counted type. https://doc.rust-lang.org/std/rc/struct.Rc.html

          Also, boxing (heap-allocating) data structures moves you back from a borrowing situation to an ownership situation, which is generally easier.

          I recently made an advanced workshop with Servo people and the general gist was: most values that travel far within the program should be handled through owned data. The veterans solution is: don’t borrow for too long :). This is intuitive: borrows are pointers and pointer structures get harder with each layer, so does the lifetime situation.

          I wish I had a good example at hand quickly, if I find one, I’ll blog about it.

          1. 2

            Thanks for the tip. That already makes some sense to me similar to concept of avoiding action at a distance. You might still want to keep developing the idea further, though, since folks keep tripping up on this stuff.

          2. 1

            As a newbie I came across to that advice couple of times but my impression is that if I use reference counting or similar approaches instead of borrow-checker, I am afraid to end up with a code that is not designed with borrow-checker in mind.

            With all toy projects I tried, I find myself changing things a lot between my first attempt of designing an API and clearing up all borrow-checker newbie mistakes.

            In that regard, so far, I wasn’t able to end up with good designs and still don’t feel comfortable with ownership idea at all.

            1. 5

              As a newbie I came across to that advice couple of times but my impression is that if I use reference counting or similar approaches instead of borrow-checker, I am afraid to end up with a code that is not designed with borrow-checker in mind.

              Hm, so. In the end, the borrow-checker is a validity check. Not needing the borrow check at certain places is not avoiding it. People feel like a cheat for not using a language feature, but that’s really not the case.

              With all toy projects I tried, I find myself changing things a lot between my first attempt of designing an API and clearing up all borrow-checker newbie mistakes.

              In that regard, so far, I wasn’t able to end up with good designs and still don’t feel comfortable with ownership idea at all.

              It’s part of learning a language (and not to be understanded) to come to good designs. I generally recommend starting with a bad/mediocre design and than refactoring. I have projects I rewrote 4 or 5 times to learn. I can get a couple of hints there, though.

              • Defining your own types is very powerful
              • APIs in Rust have to cover three context cases: owned, borrowed, mutably borrowed
              • You rarely have to take Rc and similar in signatures. Pretty often, you can use them and then pass them into functions that just take a plain borrow. You need Rc to get the data across your program.
              • There’s usually a layer in your program that distributes data between components and then parts that do work and calculations. A sharp seperation here helps a lot, as borrowing/ownership problems usually show at the edges of the components.
      2. 1

        I find rust hard because the way it hides complexity feels different. Macros seem to be necessary to offer usable APIs but make me feel like I’m missing some important details.

        I expect I’ll be able to get over this but it makes me choose other tools when I want to get something done.