|
|
Log in / Subscribe / Register

Rust Keyword Generics Progress Report: February 2023

Rust Keyword Generics Progress Report: February 2023

Posted Feb 24, 2023 3:09 UTC (Fri) by xi0n (guest, #138144)
Parent article: Rust Keyword Generics Progress Report: February 2023

While I appreciate the attempts of bringing a limited form of monadic typeclasses into Rust, I'm disappointed it only focuses on ?async and ?const. It completely ignores a much bigger source of "function coloring" problem that's largely unique to the language: mutability.

Right now, many libraries (including std) rely purely on naming convention to distinguish mutable and immutable methods. Both variants also have to be written separately, leading to proliferation of pairs such as get/get_mut, as_ref/as_mut, as_deref/as_deref_mut, and sometimes also traits (Deref/DerefMut) and various wrapper types (e.g. Ref and Mut in Bevy). Unlike async or even const, this duplication affects basically any Rust codebase. Having something like ?mut so that you can at least write methods that are generic over `&?mut self` would go a long towards reducing API cruft.


to post comments

Rust Keyword Generics Progress Report: February 2023

Posted Feb 25, 2023 21:37 UTC (Sat) by NYKevin (subscriber, #129325) [Link] (2 responses)

I think the argument against this is some variation of "mut is syntactic salt."

In other words:

* Immutable (shared) references have weaker constraints than mutable (exclusive) references.
* If we implicitly promote a reference to mut, then we impose stronger constraints on your program, which may not be obvious from the call-site.
* Those additional constraints may prove difficult to explain in compile errors, since you may not realize which of your references are mut. The compiler would have to explain how it monomorphized all potentially relevant &?mut annotations, and there might be a lot of them (e.g. "Z is mutable, but you borrow it again over here. Z is mutable because Y is mutable, and Y is mutable because X is mutable, and...").
* More generally, taking &mut everywhere is probably a Bad Idea in the first place (for the same reason that const-correctness is so important in C++).
* Therefore, we don't want to hand you a mutable reference unless you explicitly ask for one.
* The easiest way to accomplish that is to have two methods with different names. Inventing exceptional syntax for an operation that would still require the call-site to manually select a specialization would be pointless.

But I don't work on Rust, so the above is just my best guess.

Rust Keyword Generics Progress Report: February 2023

Posted Feb 26, 2023 11:19 UTC (Sun) by mb (subscriber, #50428) [Link] (1 responses)

> The easiest way to accomplish that is to have two methods with different names

Yes. I completely agree. We must have separate functions that the caller explicitly chooses from, for mutability.

But I sometimes wish there would be some help from the language to make implementing these functions easier.
For example for simple reference-getter functions we basically just duplicate the function (with added mut).

I'd sometimes like to have something like this:

fn get{_ref|_mut}(& ?mut self) -> & ?mut Foo {
& ?mut self.foo
}

It would still generate two functions with two names, but I would only have to write one.
Yes, I can do that with macros, but support from the language in the form of syntactic sugar would feel much nicer to me.

Rust Keyword Generics Progress Report: February 2023

Posted Feb 28, 2023 16:24 UTC (Tue) by plietar (subscriber, #110706) [Link]

The Pony language has some version of this called "viewpoint adaptation": https://tutorial.ponylang.io/reference-capabilities/arrow-types.html. A function signature can look like "fun get(): this->Foo", which means it returns a Foo "as seen by this": the returned reference is mutable only if the method is called on a mutable receiver.


Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds