Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I share the same pet peeve, it's not that it's not possible. It's that I would prefer copy and or move to be the default when assigning stuff. Kind of like the experience you get using STL stuff in c++.




Copy can’t be for types that aren’t copyable because there could be huge performance cliffs hiding (eg copying a huge vector which is the default in c++).

But Rust always moves by default when assigning so I’m not sure what your complaint is. If the type declares it implements Copy then Rust will automatically copy it on assignment if there’s conflicting ownership.


I have been thinking about how to express it.

My complaint is that because moves are the default, member access and container element access typically involves borrowing, and I don't like dealing with borrowed stuff.

It's a personal preference thing, I would prefer that all types were copy and only types marked as such were not.

I get why the rust devs went the other way and it makes sense given their priorities. But I don't share them.

Ps: most of the time I write python where references are the default but since I don't have to worry about lifetimes, the borrow checker, or leaks. I am much happier with that default.


You're not talking about copying values. You want it to be easy to have smart references and copy them around like you do in Python and Java, but it's more complicated in Rust because it doesn't have a GC like Python and Java.

In Rust, "Copy" means that the compiler is safe to bitwise copy the value. That's not safe for something like String / Vec / Rc / Arc etc where copying the bits doesn't copy the underlying value (e.g. if you did that to String you'd get a memory safety violation with two distinct owned Strings pointing to the same underlying buffer).

It could be interesting if there were an "AutoClone" trait that acted similarly to Copy where the compiler knew to inject .clone when it needed to do so to make ownership work. That's probably unlikely because then you could have something implement AutoClone that then contains a huge Vector or huge String and take forever to clone; this would make it difficult to use Rust in a systems programming context (e.g. OS kernel) which is the primary focus for Rust.

BTW, in general Rust doesn't have memory leaks. If you want to not worry about lifetimes or the borrow checker, you would just wrap everything in Arc<Mutex<T>> (when you need the reference accessed by multiple threads) / Rc<RefCell<T>> (single thread). You could have your own type that does so and offers convenient Deref / DerefMut access so you don't have to borrow/lock every time at the expense of being slower than well-written Rust) and still have Python-like thread-safety issues (the object will be internally consistent but if you did something like r.x = 5; r.y = 6 you could observe x=5/y=old value or x=5/y=6). But you will have to clone explicitly the reference every time you need a unique ownership.


No, I fully understand the difference. I am just saying since I don't have a GC, I would rather have the system do copies instead of dealing with references.

At least as long as I can afford it performance wise. Then borrowing it is. But I would prefer the default semantics to be copying.


> At least as long as I can afford it performance wise. Then borrowing it is. But I would prefer the default semantics to be copying.

How could/would the language know when you can and can't afford it? Default semantics can't be "copying" because in Rust copying means something very explicit that in C++ would map to `is_trivially_copyable`. The default can't be that because Rust isn't trying to position as an alternative for scripting languages (even though in practice it does appear to be happening) - it's remarkable that people accept C++'s "clone everything by default" approach but I suspect that's more around legacy & people learning to kind of make it work. BTW in C++ you have references everywhere, it just doesn't force you to be explicit (i.e. void foo(const Foo&) and void foo(Foo) and void foo(Foo&) all accepts an instance of Foo at the call site even though very different things happen).

But basically you're argument boils down to "I'd like Rust without the parts that make it Rust" and I'm not sure how to square that circle.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: