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

Vadim vadimcn at gmail.com
Thu Jan 2 14:49:53 PST 2014


I'd say it should be i(mut x, ...), though in this case inferring borrow is
not possible because of the lambda.   But if this were a standalone
function, e.g. the f() above, one could write "i(mut x, f);"

Regarding mutation-polymorphic generics, yes, it may not be possible to
mut-annotate them.  I would just let it slide for "pass-through" types like
T, but require annotations in non-generic code.
Not the best solution, but it just bothers me that we worry about the
"mutability hazard" at the top level of the call chain, but then completely
forget about it inside the callee.

Vadim




On Wed, Jan 1, 2014 at 10:18 PM, Patrick Walton <pcwalton at mozilla.com>wrote:

> On 1/1/14 10:06 PM, Vadim wrote:
>
>> Well, since requiring '&' at the original borrow site doesn't really
>> prevent the "unexpected mutability" problem, why not drop it and
>> eliminate a bunch of noise from Rust sources?
>>
>
> But it does eliminate mutation of lvalues.
>
>  And, again, if
>> "unexpected mutability" is what concerns people, "mut" annotation is the
>> better way to fix that, IMHO.
>>
>
> I don't know if it's a coherent proposal. Consider these four function
> signatures, each of which might mutate their arguments:
>
>     fn f(x: &mut int) { ... }
>
>     fn g(x: (&mut int, &mut int)) { ... }
>
>     struct S<'a> {
>         a: &'a mut int,
>         b: &'a mut uint,
>     }
>     fn h(x: S) { ... }
>
>     fn i<T>(x: T, f: |T|) { f(x) }
>
> How might `i` mutate its argument? Consider function `j`:
>
>     fn j() {
>         let mut x = 3;
>         i(&mut x, |ptr| *ptr = 5);
>     }
>
> So `i` mutated its argument. So how should you be forced to notate that?
> Should you have to write:
>
>     fn i<T>(x: T, f: |T|) { f(mut x) }
>
>     ... i(&mut x, |ptr| *ptr = 5);
>
> Or:
>
>     fn i<T>(x: T, f: |T|) { f(x) }
>
>     ... i(mut &mut x, |ptr| *ptr = 5);
>
> Or:
>
>     fn i<T>(x: T, f: |T|) { f(mut x) }
>
>     ... i(mut &mut x, |ptr| *ptr = 5);
>
> And that's just a simple example: start throwing in existential types like
> traits and it becomes clear that you really can't tell from the program
> where mutation could possibly happen, because the types are hiding
> mutability from you. And that's fine--existential types and generics
> deliberately permit that abstraction. But it does mean, I think, that we
> can't meaningfully talk about a sound and complete "mut" annotation at call
> sites.
>
> Patrick
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140102/9e193259/attachment.html>


More information about the Rust-dev mailing list