Short version of my question:
Why doesn't rust require "mut" param prefix at call sites? i.e. to
avoid "non-const ref badness" that C++ has?
Longer version of my question:
Since this question was asked recently by vadim and not really
answered clearly (imo), I'm also including this longer verbose version
of my question.
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. 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++ 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.
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
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.
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.
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" ?
// ---[ funcA.rs ]-----------------------
fn funcA(i: &int) -> int{
return 2**i;
}
// ---[ funcB.rs ]-----------------------
fn funcB(i: &mut int) -> int {
*i += 1;
return 0;
}
// ---[ funcC.rs ]-----------------------
fn funcC(i: &int) -> int {
return 3**i;
}
// ---[ funcD.rs ]-----------------------
fn funcD(i: &int) -> int{
return 2**i;
}
// ---[ main.rs ]-----------------------
fn foo(i: &mut int) {
*i += 1;
funcA(i);
funcB(i); // no mut!
funcC(i);
funcD(i);
}
fn main() {
let mut i: int = 0;
foo(&mut i);
println!("{}", i);
}
Martin
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev