[rust-dev] Why doesn't rust require "mut" param prefix at call site?

Patrick Walton pcwalton at mozilla.com
Wed Jan 1 15:55:10 PST 2014


On 1/1/14 3:49 PM, Martin Olsson wrote:
> For example in C the call "f(a,&b);" might modify "b" but not "a" so the
> "&" token acts as a "call site heads-up flag" when reading the code.

Same in Rust.

> In
> C# the "out/ref" keywords are mandatory at the call site if the callee
> uses them in its param declaration so there you also get a little in
> hint when reading the code near the call site.

C# has neither first-class pointers nor first-class references, so it 
isn't really a comparison.

> C++ of course has
> non-const references so "f(a,&b);" might modify both "a" and "b" so the
> hint is missing and I really have to look up the code for "f()" to be
> sure. If some function foo() passes "a" to a bunch of functions then I
> have to find each such function and check if "a" can be modified or not,
> so potentially I have to open a bunch of files and read code there
> before I can fully understand the code near the call sites.

That's right, and that's why Rust doesn't do this.

> Because of this many large C++ projects have coding styles that disallow
> non-const refs. See for example the google C++ coding style guide:
> http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Reference_Arguments#Reference_Arguments

Google's style guide allows mutable pointers, which are more like Rust 
references in this regard (except that pointers can be null in C++ and 
can't in Rust).

>
> Right now, it seems that rust works similar to C++ in this regard,
> meaning that there is no hint at the call site that a parameter may or
> may not be modified by the function.

No, Rust works like *C*, where if you pass a mutable *pointer* that was 
already mutable down a call chain then the callee can mutate it.

What C++ allows you to do that these style guides are trying to forbid 
is to pass an *lvalue* to a function and to have that function able to 
mutate that lvalue. That is not allowed in Rust.

> In the snippet below, if I'm reading foo() in main.rs and I wonder which
> lines in foo() could possibly change the value of "i", then I have to
> open up 4 additional files and find the relevant source locations to
> double check which functions might mutate their arguments.

You already had a mutable pointer; you can pass that mutable pointer 
down the call chain.

> Why isn't it a good idea to require some parameter prefix like "mut" at
> the call site so that when I read main.rs I immediately will know which
> lines among the calls to funcA()..funcD() that might change the value of
> "i" ?

Because that would work completely like any other language with pointers 
that I know of.

Patrick



More information about the Rust-dev mailing list