1
jestdotty
90d

they say you should just do rust clone cuz it's fast enough in most cases anyway and you won't have to hassle yourself with borrowing rules as a newbie

instead my script started to crash cuz evidently I had so much in RAM Linux was thrashing between RAM and swap until it just kept giving up lol

inb4 database

Comments
  • 2
    That’s a horrible advice and a bad practice to adopt.
    If you want reference semantics, then you can't clone. And if you want value semantics, then cloning is implicit anyway.
  • 2
    @jestdotty you only need to deal with borrowing rules if you pass objects around by reference. And if you do that, then you obviously want reference semantics, otherwise you would have passed by value, which implicitly copies the object.
    So defensively copying (or cloning) an object which has been passed by reference (intended for reference semantics) is not only unnecessary but also wrong, because you lose access to the original object that you were referencing and you are left with a copy.
  • 1
    Another way to put it:

    If all you want is a copy anyway, then just pass by value and the object will be copied implicitly, which is even faster than cloning.

    And if you want to use references to pass values without the costly copy operation (in case your object is big enough), then you would have made it worse by using clone anyway. It’s more expensive than the implicit copying.

    So, either way, it’s wrong.
  • 0
    @Lensflare There are a lot of reasons why something might not be Copy, such as type erasure (which itself can be required for multiple reasons other than semantics) and runtime sized collections.
  • 1
    @lorentz sure, but that doesn’t invalidate what I have said:
    It’s a very bad idea to clone() everything so that you don’t have to deal with borrowing rules.
  • 3
    I agree that this is terrible advice, you should learn your options, consider some examples of behaviour in other languages that's analogous to each option, and decide which one matches your strategy best

    - Owned, deep copied: Clone

    - Shared, immutable: Rc/Arc (followup: do you use threads?)

    - Shared, mutable: Rc RefCell / Arc Mutex or RwLock (followup: identify critical sections wrt. ordering)

    - Borrowed, discarded before function returns: &, &mut
  • 1
    @lorentz on a side note, the equivalent of Rust's Copy (Copyable), has been introduced to Swift recently and this is the sole reason why I was able to understand your comment :)

    I love it when great languages steal good stuff from each other.
  • 2
    Borrowing and cloning are just two of many things you can do to make a value appear in multiple places. Most high level languages use an Arc Mutex implicitly. You don't want to do that everywhere because you chose Rust partly for its speed, but you should consider the entire spectrum between that and the fundamental Clone and borrow.
  • 2
    @Lensflare I'm actually not a fan of how universally Copy is used. It's equivalent to C++'s TriviallyCopyable, which is a concept C++ deliberately only uses for C interop. In practice the difference between copying a Rc and copying an usize is only externally visible if you copy very large collections. A distinction between an (implicit?) cheap clone and arbitrary cost clone would be more useful.
  • 0
    Dropping an object is usually about as expensive as cloning it, yet drops are always implicit.
  • 1
    @jestdotty Lifetimes are closely tied to stack frames. If it may not be practical to keep the referenced data in place on the stack (as it often isn't), avoiding lifetimes may be better. I use a lot of Rc.
  • 1
    @jestdotty I like to expand my understanding of lifetimes by trying to express complex relationships with them, but if I can't do it in a reasonable time it's not illegal to use something simpler. If this is a shared project, you probably only want to use lifetimes when they're straightforward and easy, because leaving riddles for the other devs isn't great for getting shit done, or for team morale.
  • 0
    @jestdotty I never said something like that "if you wanted an object to be borrowed". That doesn’t make sense. Don’t put words in my mouth. It was not what I was trying to say.

    You clearly have a severe lack of understanding of concepts and terminology that is required for a language like Rust.

    And instead of asking for details, you just try to make me look dumb by saying that what I say doesn’t make sense.
    Great attitude! Keep doing that!
  • 0
    @lorentz you understood what I said, right?
  • 1
    @Lensflare I agree with the main point that cloning everything is wrong, but I don't think your explanation is correct or helpful, and it's confusing because it's unclear whether you're talking about Copy and Ref or the concept of a copy and a reference. Plus, "object" is just all around not a useful term in Rust. What architects might call an object concretizes to some combination of resources created and released at the same time that probably won't even refer to each other, and the only reason they share a timespan of existence is that this is the definition of an object.
  • 1
    correction: object is more a pattern than a language feature, and it has little to do with memory management.
  • 0
    @Lensflare I don't think your explanation is helpful because it describes a dichotomy where reality is a spectrum.
  • 1
    @Lensflare Wow, sorry about that all, I can be a dick when I'm hungry. No I didn't understand your explanation because I don't know what reference semantics means in this context.
  • 1
    @lorentz I was trying to be as generic as possible and also a bit language agnostic.
    I agree with what you said but I don’t see how I could have explained it more clearly without complicating it a lot more.
  • 1
    @Lensflare It's certainly complicated. I think Jestdotty here is struggling with language specifics.
  • 1
    @lorentz reference semantics is when your intent is to pass an object and being able to read and write to it as if it was the original object. So all changes happening to the original object are reflected in your handle and vice versa. This is opposed to a copy.

    Whenever you pass an object, you always make a (maybe not so conscious) decision to pass it by reference or by value (implicit copy). Or at least you should, otherwise I don’t know how you can ever hope to write correct code.

    By "object" I really mean anything that is an instance of any type.
  • 1
    @Lensflare Thanks, that cleared it up a bit. Do you think it makes sense then to say that reference semantics in Rust requires one of the Cell or Lock containers, and everything else - including references - has value semantics, since no change to the value is allowed from the sender or the recipient?
  • 0
    @lorentz depends on the context and intent.
    Passing references means value semantics for the references themselves but reference semantics for the objects that the references point at.
  • 0
    @jestdotty you didn’t ask. You basically said that you don’t understand anything, leaving no specific thing for me to answer to.
    Then you said that what I said makes no sense and claimed that I said something that I didn’t.
    Also what you think that I was saying doesn’t make any sense to me so I don’t even know what to answer here.
    Our communication seems incompatible.
Add Comment