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

2014-01-03 Thread Stefan Plantikow
Hi,

Am 02.01.2014 um 07:18 schrieb Patrick Walton pcwal...@mozilla.com:
 
 
 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.
 

Maybe completely off here but why is mutability not tracked by the region 
system? Wouldn’t that help solve this issue? i.e. assignment to a mutable 
lvalue would only be allowed from an rvalue in a mutable region.   Haven’t 
thought about how that relates to freezing/thawing.


Cheers,


Stefan


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-03 Thread Patrick Walton

On 1/3/14 2:25 AM, Stefan Plantikow wrote:

Maybe completely off here but why is mutability not tracked by the
region system? Wouldn’t that help solve this issue? i.e. assignment
to a mutable lvalue would only be allowed from an rvalue in a mutable
region.   Haven’t thought about how that relates to
freezing/thawing.


It kind of is, in that mutation generally requires a unique ownership 
path. See the comments in the borrow checker for more details.


Patrick

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-02 Thread martin
Thanks, that explains it.Martin 
- Original Message -
From: Patrick Walton 
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


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-02 Thread Vadim
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 pcwal...@mozilla.comwrote:

 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 iT(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 iT(x: T, f: |T|) { f(mut x) }

 ... i(mut x, |ptr| *ptr = 5);

 Or:

 fn iT(x: T, f: |T|) { f(x) }

 ... i(mut mut x, |ptr| *ptr = 5);

 Or:

 fn iT(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


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-01 Thread Patrick Walton

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

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-01 Thread Patrick Walton

On 1/1/14 3:55 PM, Patrick Walton wrote:

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


Err, I mean unlike.

Patrick

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-01 Thread comex
On Wed, Jan 1, 2014 at 6:49 PM, Martin Olsson mar...@minimum.se wrote:
 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?

Well, to be somewhat extreme, in a function like

struct S { a: mut int, b: mut int }
fn f(s: mut mut S) ...
fn g(s: mut mut S) { f(s) }

what sort of muts does g need?
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-01 Thread Vadim
I think the real answer is at this point nobody wants to tweak basic Rust
syntax yet again.   See the other thread about Rust roadmap, etc.  Oh
well...


On Wed, Jan 1, 2014 at 3:49 PM, Martin Olsson mar...@minimum.se wrote:

 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
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-01 Thread Patrick Walton
There is no real answer beyond the one I already gave: that we are already 
precisely as explicit as C, that Rust references do not actually have the 
hidden mutation hazard of C++ references, and that changing would place the 
language in a different space entirely. Please don't suggest that I am (or that 
anyone else on the list is) being dishonest.

Patrick

Vadim vadi...@gmail.com wrote:
I think the real answer is at this point nobody wants to tweak basic
Rust
syntax yet again.   See the other thread about Rust roadmap, etc.  Oh
well...


On Wed, Jan 1, 2014 at 3:49 PM, Martin Olsson mar...@minimum.se
wrote:

 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
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev





___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-01 Thread Palmer Cox
I could be pretty wrong, so if I am, I apologize and please ignore. Anyway,
I thought I once read somewhere that when you call a function defined like:

fn foo(a: mut int) { ... }

with code that looks like

fn bar(b: mut int) {
foo(b);
}

that despite what it looks like, you aren't really passing the value b into
the function foo(). My understanding, is that when you pass a reference to
foo(), that it takes ownership of that reference making it inaccessible to
any following code. Since this is generally not what anyone wants, Rust
silently re-borrows b and passes that re-borrowed version of the reference
to foo() which takes ownership of it. Since b wasn't actually passed to
foo(), code after the call to foo() can continue to use b since bar() still
owns b.

Anyway, if that is all correct, and I'm not sure how likely that is all to
be correct, it feels like what this email thread really boils down to is a
proposal to eliminate automatic re-borrowing of a mut to mut when
invoking a function. I'm may be wrong, but, I'm also under the impression
that manually re-borrowing would look something like:

foo(mut (*b))

which is extremely unpleasant, so, I'd imagine that the 2nd part of the
proposal is to make some sort of nicer syntax for that.

To me, this doesn't sound as much like a proposal for a change in syntax as
a proposal to remove a bit of magic that Rust is currently doing. I don't
know that I'm necessarily in favor or that though, since it would certainly
make code more wordy. That wordiness might be nice, however, if it makes it
clearer where variables might be mutated (eg: imagine that foo() is
originally defined to take a  ,so bar() assumed that the variable won't be
mutated. However foo() is later redefined to take a mut which silently
breaks bar()'s assumption about foo()).

-Palmer Cox





On Wed, Jan 1, 2014 at 11:41 PM, Vadim vadi...@gmail.com wrote:

 I think the real answer is at this point nobody wants to tweak basic Rust
 syntax yet again.   See the other thread about Rust roadmap, etc.  Oh
 well...


 On Wed, Jan 1, 2014 at 3:49 PM, Martin Olsson mar...@minimum.se wrote:

 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
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev mailing list
 

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

2014-01-01 Thread Patrick Walton

On 1/1/14 9:13 PM, Palmer Cox wrote:

To me, this doesn't sound as much like a proposal for a change in syntax
as a proposal to remove a bit of magic that Rust is currently doing. I
don't know that I'm necessarily in favor or that though, since it would
certainly make code more wordy. That wordiness might be nice, however,
if it makes it clearer where variables might be mutated (eg: imagine
that foo() is originally defined to take a  ,so bar() assumed that the
variable won't be mutated. However foo() is later redefined to take a
mut which silently breaks bar()'s assumption about foo()).


That's a much more interesting question. I do worry about the verbosity 
though, as you said.


In general I feel like we should either have autoborrowing in as many 
places as reasonably possible or autoborrowing nowhere.


Patrick
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-01 Thread Vadim
On Wed, Jan 1, 2014 at 9:12 PM, Patrick Walton pwal...@mozilla.com wrote:

 There is no real answer beyond the one I already gave: that we are
 already precisely as explicit as C, that Rust references do not actually
 have the hidden mutation hazard of C++ references, and that changing would
 place the language in a different space entirely.


Patrick, I disagree with this point.  Rust references *do* have hidden
mutation hazard, as do C's and C++'s pointers.  In all three, mutation
hazard is only obvious when you take an address of a stack variable.
After that, when you already have a pointer, you pass it around, and never
know who might mutate the underlying object.  And let's not forget about
the heap-allocated objects, which start out as pointers in the first place.

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?   And, again, if unexpected
mutability is what concerns people, mut annotation is the better way to
fix that, IMHO.


  Please don't suggest that I am (or that anyone else on the list is) being
 dishonest.


My apologies, I didn't mean to imply that.

Vadim
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-01 Thread Patrick Walton

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 iT(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 iT(x: T, f: |T|) { f(mut x) }

... i(mut x, |ptr| *ptr = 5);

Or:

fn iT(x: T, f: |T|) { f(x) }

... i(mut mut x, |ptr| *ptr = 5);

Or:

fn iT(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

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-01-01 Thread Daniel Micay
On Thu, Jan 2, 2014 at 1:06 AM, Vadim vadi...@gmail.com wrote:

 And let's not forget about the heap-allocated objects, which start out as 
 pointers in the first place.

Unique pointers have value semantics so this shouldn't be relevant to
the visibility of mutation. The consensus is already to remove the
auto-coercion of `~T` to `mut T` because it doesn't make any sense.
The auto-coercion to `T` will probably either be removed or extended
to `T` too, but that hasn't been decided (or discussed much).
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev