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

You can write Rust code with almost no lifetine annotations. That's heavily dependent on the domain, of course. But for relatively simple function signatures they are usually inferred correctly, and you can often just clone instead of requiring references.


Pretty sure if you’re deserializing a structure with borrowed references you need lifetime annotations. Copying things around to pacify the compiler hardly seems elegant.


Sure, but that's a performance vs ease of use decision.

Often you don't need to care about the extra allocations and can just deserialize to owned types.

The code for owned deserialization certainly ends up looking more elegant.


It’s not just performance, but you now have to go back and update every instance of that struct to reflect the change in ownership of that member if you can even change the member in the first place (e.g., you can’t change the type of a member of the struct itself is defined in a third-party package). Moreover, some instances of your struct might be in a tight loop and others might not, but now you’re committing to poorer performance in all cases. Maybe you can box it (although IIRC I’ve run into other issues when I tried this) but in any case this isn’t the “elegance” I was promised. Which is fine, because Rust is a living, rapidly-improving language, but let’s not pretend that there is an elegant solution today.


Libraries can be (and some actually are) designed with that in mind, with COW (copy on write( types that can be either borrowed or owned. Speaking of performance, kstring (of liquid) goes one step further with inline variants for short strings.

I want to say that seems like a valid concern but in practice I've seen it come up only rarely.


Yes, you can clone all day long and just reuse variable names as if you were writing JavaScript, but what does that do to your memory allocation?


Most languages just clone all day long, it's not that bad, rust clones (like most languages) are just to the first reference counted pointer after all.


Well, yes and no.

Eg cloning a string leads to an extra allocation and a memcopy.

If you want to get a similar performance profile to GC languages, you have to stick your types behind a `Rc<T>>/Arc<T>` or `Rc<RefCell<T>> / Arc<Mutex<T>>` if you need mutability.

But modern allocators hold up pretty well to a GC, which amortizes the allocations. The extra memcopying can be less detrimental than one might think.


“Yes and no” is too generous; most languages clone only very infrequently (basically only for primitives where there is no distinction between a deep and shallow copy). For complex types (objects and maps and lists) they pass references (sometimes “fat” references, but nevertheless, not a clone).


To be clear, JS doesn’t require cloning because it has a gc. Not sure what you’re getting at with reusing variables names...


What I mean is, if one does:

  const obj1 = { a: 32, b: 42 };
  function foo(ref) { ref.a = 0; }

  foo(obj1);
  console.log(obj1);
in JavaScript, one is just using the variable name as a "holder" of some value. One doesn't have to designate that that variable is being passed by reference. If one wanted to actually copy that object, they'd have to devise a mechanism to do so. In Rust, if someone doesn't specify, using the & symbol, that something is a reference, it'll end up moving the value.

Basically all I was saying is one can not approach writing Rust with a Java/JavaScript mindset. (That a variable is just a bucket holding a value). Care needs to be taken when referencing a variable as it may need to be moved, copied/cloned or referenced. In the case of copying, another memory allocation is done. So if someone approaches Rust from the standpoint of "this word represents a value, and I'm going to use it all over the place", they can find themselves blindly allocating memory.


Oh, by “reuse variable names”, you simply mean that values aren’t moved, i.e., that JS lacks move semantics or an affine type system. That’s a bit different to “reusing variable names”, which you can do in Rust as well provided the variable holds a (certain kind of?) reference.




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

Search: