[Idea] Improving the ergonomics when using Rc

That assumes that const fn will never be able to make escaping allocations. That may not be coming anytime soon but it would certainly be useful so I wouldn’t rule it out yet.

3 Likes

Only skimmed the discussion here, so I apologize if I’m saying something that hasn’t been said before.

In Rc’s case, the clone() is particularly annoying because Rc can be used in situations where you intentionally want to handwave memory management. Eg because the particular part of the code you’re working in is high-level code where performance issues are going to be much more dramatic than an indirect pointer access or a cache miss, and the Rc clone()s could lead to you missing the forest for the trees. Or a “penny-wise, pound-foolish” style of programming.

The best argument I can think of against it is “that’s not the niche Rust is supposed to occupy, you should use a different language”. But even assuming that’s an option, that means you lose all the expressiveness of the type system and have to re-expose that in the other language.

I unfortunately can’t think of a good solution here. To me, it’s somewhat distinct from Copy and Clone. Lumping a reference count increment in with clone seems like an unfair grouping. It probably isn’t as cheap as a small Copy, but in all but the most tight loops, it’s probably going to be insignificant compared to any other clone(). But beyond the potential backwards compatibility issues, adding another trait seems risking trait pollution.

EDIT: Continued reading a bit more and I so far tenatively like @illicitonion 's solution. This seems like a decent way of labeling a high-level scope as such so that you can tell that any clone()s involved are actually significant and worthy of note. Eg doing syscalls or copying a substantial amount of data.

2 Likes

My assumption is that if const fn grows the ability to return allocations we'll also have sufficient compiler technology available to enforce a no-allocation requirement for AutoClone impls. Is that reasonable?

Even beyond Rc though, sometimes it would be better if String/&str/Cow<str> were all collapsed into one type which you could split/append/copy willy-nilly, like in (for instance) Python. On the other hand there are cases where performance matters and even simple copies are relevant.

This is even more general than just Clone though. Sometimes I'd like panics/aborts to be explicit so I can do things like (eg.) catch memory allocation errors. Other times even Result/? is just code-noise and I'd prefer to have silent exceptions.

It seems like what we really need is a heirarchy of languages which make the explicitness/expressiveness trade-off differently, the ability to intermix them and the ability to type-check across them. Kinda like how we translate Rust down to MIR, except if MIR retained all the type-safety of Rust, and also another language in the opposite direction which has implicit memory management and compiles to Rust.

2 Likes

That's a good idea- though I'm not sure what such a design would look like or how we might be future compatible with it. Probably worth coming up with some ideas as part of the design of AutoClone.

On the other hand I worry that any attempt to enforce that requirement would balloon into some kind of allocation-as-an-effect system, way overshooting the complexity budget.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.