Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Vadim
I found this 
posthttp://smallcultfollowing.com/babysteps/blog/2012/10/01/moves-based-on-type/by
Niko, and it seems that at the time everyone agreed that implicit
moving
actually makes things more clear.   Why is this different now, only a year
later? :-)

Ok, but serieosly, I allow that this is different for function arguments vs
regular code in the function body.  So maybe the right thing to do *is *to
stop moving function parameters by default?



On Tue, Nov 19, 2013 at 5:35 PM, Vadim vadi...@gmail.com wrote:

 If the function is not going to mutate it, I don't really care if it's
 by-ref or by-value.   That's why I said const T, not T.   Well,
 except for the case when a function caches a reference to something which I
 later mutate.   But borrow checking will prevent that.

 I would also be totally fine with letting the compiler figure out how
 immutable arguments are passed (based on data type size, existence of
 destructors, and whatnot).  This might not be the best idea for binary
 compatibility of public APIs, but I don't see why it can't be done with
 crate-private functions.




 On Tue, Nov 19, 2013 at 5:07 PM, Ziad Hatahet hata...@gmail.com wrote:

  Personally I would prefer if  in Rust worked similar to const T in c++

 In that case, you would not be able to tell whether a function argument
 was passed by value or by reference. I actually like this feature about
 Rust (C# has it too with the `ref` keyword).

 --
 Ziad


 On Tue, Nov 19, 2013 at 4:54 PM, Vadim vadi...@gmail.com wrote:

 So why did Rust adopt auto-moving instead of explicit moving?   If the
 second example had to be written as foo(move a) there would be no
 confusion.   The and the third example should arguably be sort(mut
 a.as_mut_slice()).

 Personally I would prefer if  in Rust worked similar to const T in c++
 (i.e. for most intents and purposes you can treat a reference as a value),
 otherwise half of the arguments on each function call will have to be
 adorned with ampersands.

 Can we have it such that foo(a) would be guaranteed to not mutate or
 move a and require mut or move prefix otherwise?


 ___
 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] Removing some autoref magic

2013-11-20 Thread Igor Bukanov
On 20 November 2013 02:07, Ziad Hatahet hata...@gmail.com wrote:
 Personally I would prefer if  in Rust worked similar to const T in c++

 In that case, you would not be able to tell whether a function argument was
 passed by value or by reference. I actually like this feature about Rust (C#
 has it too with the `ref` keyword).

In the safe code there is no difference if the value is passed via a
copy or as T. Also as I learned recently the Rust compiler already
optimizes T parameters into T for small-sized T at --opt-level=3. So
effectively T parameter became a notation for the most efficient
passing of arguments of type T.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Niko Matsakis
On Wed, Nov 20, 2013 at 12:30:59AM -0800, Vadim wrote:
 I found this 
 posthttp://smallcultfollowing.com/babysteps/blog/2012/10/01/moves-based-on-type/by
 Niko, and it seems that at the time everyone agreed that implicit
 moving
 actually makes things more clear.   Why is this different now, only a year
 later? :-)

I stand by the arguments I made in that post. My experience at least
has been that implicit moves have been much more pleasant to work with
than explicit ones, and the language is simpler as well.


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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Sanghyeon Seo
First, I am speaking for myself and not my employer.

 The current proposal is to remove all autoref except for function
 invocations and indexing operations. The method of creating T from ~T
 would be `let foo: T = foo` or `*foo`. Vectors and strings can't
 currently benefit from the `*foo` syntax, but they will hopefully be
 able to do such once DST lands. In the meantime coercion via type
 ascription will work and they also have `as_slice` methods.

I am against this proposal. As I understand, we will still keep
autoref, autoborrow, etc. in method calls. So I don't think inconsistency
argument holds. Neither does local readability argument.

For local readability, which I agree is important, we have naming
conventions naming methods taking mut self with mut_* and
methods taking by-value self with move_*. (Methods normally take
self.) And with better tooling, function signature should be locally
accessible to the call site.

I am not in the camp of less compiler magic. Some people
seem to argue for removal of automatic coercions even in method calls,
and I am very much against that idea. Someone's magic is other's
convenience.

As for #10504, perceived asymmetry seems to originate from
the confusion of value and reference. As for inconsistency of
automatic coercions, I propose we add automatic coercions to
return expression, and any other places as we discover other
missing places.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Bill Myers
Have you considered making deref the default instead and requiring moves to use 
an explicit move keyword?

Basically, from this hypothetical syntax to current one:
- x = x
- mut x = mut x
- move x = x

One could even make the  implicit in parameter types in function declarations 
unless the move keyword is used, so we would have (new = old syntax):
- fn(self, ...) = fn(self, ...)
- fn(mut self, ...) = fn(mut self, ...)
- fn(move self, ...) = fn(self, ...)

Regarding owned pointers, one could introduce this syntax:
let *x = func_that_gives_owned_pointer()

which makes x a variable of type T referring to the contents of the owned box, 
and thus derefed to  when passed to a function as above without having to 
write *x in the function call.

One could then add a new #x or similar syntax that would get back to the 
owned pointer.

Not sure if all this is a good idea, just throwing it out there. I actually 
think keeping autoref/autoderef is probably better.

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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread spir

On 11/20/2013 02:51 PM, Bill Myers wrote:

Have you considered making deref the default instead and requiring moves to use an 
explicit move keyword?

Basically, from this hypothetical syntax to current one:
- x = x
- mut x = mut x
- move x = x

One could even make the  implicit in parameter types in function declarations unless the 
move keyword is used, so we would have (new = old syntax):
- fn(self, ...) = fn(self, ...)
- fn(mut self, ...) = fn(mut self, ...)
- fn(move self, ...) = fn(self, ...)


I like this proposal, because afaik it matches the common use case.
Also, it would make things easier to learn, understand, and use, for people not 
used to move semantics (even less to it as default / implicit case). I do 
struggle with move; making it explicit would help (also when reading it other 
people's code).


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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Patrick Walton

On 11/19/13 9:42 PM, Tommi wrote:

Our problem is that, given let arg: ~A;, seeing only foo(arg) in code
doesn't tell us whether arg is moved or borrowed. The proposed solution
is that auto-borrowing in that context would be deprecated and thus
would require an explicit borrowing: foo(*arg). Now, given that it
seems that the upcoming UFCS would simply re-write arg.foo() to
foo(arg), it would mean that seeing only arg.foo() in code doesn't tell
us whether arg is moved or borrowed. Thus, the proposed solution would
fix only half of the problem.


Again, I don't see this as an argument against the proposal. The dot 
operator is always magical. Magic on one place doesn't justify magic 
everywhere.


Patrick

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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Patrick Walton

On 11/20/13 5:51 AM, Bill Myers wrote:

Have you considered making deref the default instead and requiring moves
to use an explicit move keyword?


Tried it a year ago. It was incredibly noisy. I don't want to go back to 
that world.


We saw things like:

let move x = move foo(move y);

Patrick

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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Patrick Walton

On 11/20/13 6:25 AM, spir wrote:

I like this proposal, because afaik it matches the common use case.
Also, it would make things easier to learn, understand, and use, for
people not used to move semantics (even less to it as default / implicit
case). I do struggle with move; making it explicit would help (also when
reading it other people's code).


You have to know moves to use Rust. The noise didn't aid understanding a 
year ago, and I don't think it will now.


Patrick

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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Patrick Walton

On 11/20/13 5:05 AM, Sanghyeon Seo wrote:

I am against this proposal. As I understand, we will still keep
autoref, autoborrow, etc. in method calls. So I don't think inconsistency
argument holds. Neither does local readability argument.


It is a good point that a true emphasis on consistency between methods 
and functions would have us perform auto-deref and auto-ref on all 
argument positions. Then the LHS of `.` and arguments would truly be 
treated the same way, which dovetails with UFCS pretty nicely.


I'm pretty nervous about performing auto-ref on function arguments, 
though, *especially* `mut` auto-ref. For some reason I expect that this:


let mut a = ~[x];
a.push(hi);

may mutate `a`, while:

let mut a = ~[y];
push(a, b);

will *not* mutate `a`. Do others have the same expectation?

Patrick

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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Corey Richardson
On Wed, Nov 20, 2013 at 11:37 AM, Patrick Walton pcwal...@mozilla.com wrote:
 On 11/20/13 5:05 AM, Sanghyeon Seo wrote:

 I am against this proposal. As I understand, we will still keep
 autoref, autoborrow, etc. in method calls. So I don't think inconsistency
 argument holds. Neither does local readability argument.

 I'm pretty nervous about performing auto-ref on function arguments, though,
 *especially* `mut` auto-ref. For some reason I expect that this:

 let mut a = ~[x];
 a.push(hi);

 may mutate `a`, while:

 let mut a = ~[y];
 push(a, b);

 will *not* mutate `a`. Do others have the same expectation?


I do, and I agree a lot with Niko's arguments from the meeting. I
agree that * is a bit ugly, but I prefer the ugly syntax to the
ambiguity. I don't find Kevin's argument particularly convincing;
those changes can make your code fail to compile, but *not* to
transparently behave differently (simply by changing the types of the
args).

I'm in favor of the proposal. What we have now isn't that great and
moving to an alternative is good, even if it's not the best. We can
move to something better later.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Niko Matsakis
One caveat: this e-mail made it sound as if the proposal were
universally favored at the meeting, but I at least feel conflicted,
though I may not have that clear. I started writing a response but
it got long, so I moved it to a blog post:

http://smallcultfollowing.com/babysteps/blog/2013/11/20/parameter-coercion-in-rust/

I'll just paste the text inline here, starting with the conclusion:

## What should we do?

I think we ought to experiment. It's not too hard to whip up a branch
with the two alternatives and work through the implications. I'm
currently doing the same with more stringent rules around operator
overloading, and the experience has been instructive -- I haven't yet
decided if it's acceptable or not. But that's a topic for another
post.

## Historical background

In the interest of clarity, I wanted to briefly explain some
terminology and precisely what the rules *are*. I refer to autoref
as the addition of an implicit ``: so converting from `T` to `T`, in
terms of the type. Autoderef is the addition of an implicit `*`:
converting from `T`, `~T`, etc to `T`. Finally, autoborrow is the
addition of both a `` and a `*`, which effectively converts from
`~T`, `T` etc to `T`. Autoslice is the conversion from `~[..]` and
`[...]` to `[...]` -- if we had a DST-based system, autoslice and
autoborrow would be the same thing, but in today's world they are not,
and in fact there is no explicit syntax for slicing.

Currently we apply implicit transformations in the following circumstances:

- For method calls and field accesses (the `.` operator) and indexing
  (`[]`), we will autoderef, autoref, and autoslice the
  receiver. We're pretty aggressive here, happily autoderefing through
  many layers of indirection.  This means that, in the extreme case,
  we can convert from some nested pointer type like `@T` to a type
  like `T`.
  
- For parameter passing, local variable initializers with a declared
  type, and struct field initializers, we apply *coercion*. This is a
  more limited set of transformations. We could and probably should
  apply coercion in a *somewhat* wider set of contexts, notably return
  expressions.
  
Currently we are specifically referring to what the *coercion* rules
ought to be. Nobody is proposing changing the method lookup behavior.
Furthermore, nobody is proposing removing coercion altogether, just
changing the set of coercions we apply.

### Current coercion rules

The current coercion rules are as follows:

  - Autoborrow from `~T` etc to `T` or `mut T`.
- Reborrowing from `'a T` to `'b T`, `'a mut T` to `'b mut T`,
  which is a special case. See discussion below.
  - Autoslice from `~[T]`, `[T]`, `[T, ..N]` etc to `[T]`
  - Convert from `T` to `*T`
  - Convert from a bare fn type `fn(A) - R` to a closure type `|A| - R`

In addition, I believe that we *should* have the rule that we will
convert from a pointer type `T` to an object type `Trait` where
`T:Trait`. I have found that making widespread but non-uniform use of
object types without this rule requires a lot of explicit and verbose
casting.

### Slicing

If we had DST, then slicing and borrowing are the same thing. Without
DST, there is in fact no explicit way to slice a vector type like
`~[T]` or `[T, ..N]` into a slice `[N]`. You can call the `slice()`
method, but that in fact relies on the fact that we will autoslice a
method receiver. For vectors like `~[N]` and so on, we could implement
`slice` methods manually, but fixed-length vectors like `[T, ..N]` are
particularly troublesome because there is no way to do such a thing.

### Reborrowing

One of the less obvious but more important coercions is what I call
*reborrowing*, though it's really a special case of autoborrow. The
idea here is that when we see a parameter of type `'a T` or `'a mut
T` we always reborrow it, effectively converting to `'b T` or `'b
mut T`.  While both are borrowed pointers, the reborrowed version has
a different (generally shorter) lifetime. Let me give an example where
this becomes important:

fn update(x: mut int) {
*x += 1;
}

fn update_twice(x: mut int) {
update(x);
update(x);
}

In fact, thanks to auto-borrowing, the second function is implicitly
transformed to:

fn update_twice(x: mut int) {
update(mut *x);
update(mut *x);
}

This is needed because `mut` pointers are *affine*, meaning that
otherwise the first call to `update(x)` would move the pointer `x`
into the callee, leading to an error during the second call. The
reborrowing however means that we are in fact not moving `x` but
rather a temporary pointer (let's call it `y`). So long as `y` exists,
access to `x` is disabled, so this is very similar to giving `x` away.
However, lifetime inference will find that the lifetime of this
temporary pointer `y` is limited to the first call to `update` itself,
and so after the call access to `x` will be restored. The borrow
checker rules permit reborrowing under the 

Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Thad Guidry


  may mutate `a`, while:
 
  let mut a = ~[y];
  push(a, b);
 
  will *not* mutate `a`. Do others have the same expectation?
 


But isn't there a missing context there ?  That 'a' does not necessarily
have to be mutable globally ?  But could be constrained... only in the
defined functions, or...traits...or ?

-- 
-Thad
+ThadGuidry https://www.google.com/+ThadGuidry
Thad on LinkedIn http://www.linkedin.com/in/thadguidry/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread David Piepgrass
I'm wondering something. Have the Rust developers considered the
possibility of using references instead of pointers? It seems to me
that this would eliminate a lot of the need for autoderef. Now I'm
not well-equipped to talk about Rust (some of the rules I am totally
ignorant about, e.g. I know rust has a ref keyword but the tutorial
does not mention it) so let me talk about C++ instead.

C++, of course, has references, which are exactly like pointers except
they are always implicitly dereferenced:

int y = 123;
int* x1 = y; // *x1 == y   x1 == y
int x2 = y;  //  x2 == y  x2 == y

In fact, with one small tweak, C++ could have entirely eliminated the
need for pointers (except array pointers), and references could have
been used for everything except arrays. The reason references cannot
replace pointers is that the pointer--the true identity of a
reference--is immutable. But that's easily fixable though, by defining
x2 as an lvalue:

x1 = z;
x2 = z; // Aha! We've changed the pointer inside the reference

If the second line were legal, then references could do everything
that pointers could do; in that case I think that, for consistency,
people would have eventually standardized on using references for
everything that doesn't require pointer arithmetic (i.e. arrays).
Instead we have this situation where some functions take (non-const)
T and others take T*, so sometimes you have to call functions with
foo and other times it's just foo, and the presence or absence of
 doesn't signify anything important (for example, it doesn't tell
you whether the callee mutates foo or not)

It seems to me that the majority of languages have recognized that
references are easier to work with than pointers, and not just because
you can write foo.f() instead of foo-f(). That is, I don't think
auto-deref (where foo.f() means (*foo).f()) is enough to eliminate the
pain of working with pointers instead of references.
Would it help to define ~T, T and @T as reference types rather than
pointer types? I'm sure there are some obvious objections, but perhaps
the problems could be ironed out by someone with a better grasp of
Rust.
I'd also like to comment on the removal of move. While I recognize
explicit moves everywhere might be inconvenient, I have noticed that
newbies on the list (including myself) are often confused by them.
Would a compromise be in order, in which moves are implicit except
when passing parameters to methods? I like Bill Byers' suggestion for
call-site parameters of the form move x, mut x and just x for
implicit copy / borrow. Patrick mentioned the annoyance of writing

 let move x = move foo(move y);

but


 let x = foo(move y);

doesn't sound so onerous, and it says something important about foo()
that someone reading the code might not realize.

Everyone's had their fair share of issues with autoref and autoderef,

and it's worth considering removing certain portions of it from the

compiler. The discussion around this has been rooted in the past, but

has recently been brought up as part of

https://github.com/mozilla/rust/issues/10504.


 The current proposal is to remove all autoref except for function

invocations and indexing operations. The method of creating T from ~T

would be `let foo: T = foo` or `*foo`. Vectors and strings can't

currently benefit from the `*foo` syntax, but they will hopefully be

able to do such once DST lands. In the meantime coercion via type

ascription will work and they also have `as_slice` methods.


 There are a few reasons backing this proposal:


 1. It's inconsistent to have magical autoref in some places, but not

in other places.

2. The camp of less compiler magic is better can fly their flag over

this change.

3. Code readability does not necessarily benefit from autoref on arguments:


   let a = ~Foo;

  foo(a); // reading this code looks like it moves `a`

  fn foo(_: Foo) {} // ah, nevermind, it doesn't move `a`!


   let mut a = ~[ ... ];

  sort(a); // not only does this not move `a`, but it mutates it!



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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Steven Blenkinsop
If the concern is mutability rather than details of the indirection used,
then one option would be:

let mut a = ~[y];
push(mut a, b);

It would be a bit odd to do:

let mut x = 0;
incr(mut x);

instead of:

incr(mut x);

as long as you're keeping a strict pointer vs. value mental model, but part
of the motivation of considering this in the first place is a weakening of
this model, so I'm not sure how it ends up on balance. Sort of starts to
seem like passing modes on the caller side, though still implemented using
explicit memory layout on the callee side and autoref/autoborrow acting as
the bridge.

On Wednesday, November 20, 2013, Patrick Walton wrote:

 On 11/20/13 5:05 AM, Sanghyeon Seo wrote:

 I am against this proposal. As I understand, we will still keep
 autoref, autoborrow, etc. in method calls. So I don't think inconsistency
 argument holds. Neither does local readability argument.


 It is a good point that a true emphasis on consistency between methods and
 functions would have us perform auto-deref and auto-ref on all argument
 positions. Then the LHS of `.` and arguments would truly be treated the
 same way, which dovetails with UFCS pretty nicely.

 I'm pretty nervous about performing auto-ref on function arguments,
 though, *especially* `mut` auto-ref. For some reason I expect that this:

 let mut a = ~[x];
 a.push(hi);

 may mutate `a`, while:

 let mut a = ~[y];
 push(a, b);

 will *not* mutate `a`. Do others have the same expectation?

 Patrick

 ___
 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] Removing some autoref magic

2013-11-20 Thread Patrick Walton

On 11/20/13 10:23 AM, David Piepgrass wrote:


I'm wondering something. Have the Rust developers considered the possibility of using references 
instead of pointers? It seems to me that this would eliminate a lot of the need for 
autoderef. Now I'm not well-equipped to talk about Rust (some of the rules I am totally 
ignorant about, e.g. I know rust has a ref keyword but the tutorial  does not mention 
it) so let me talk about C++ instead.

C++, of course, has references, which are exactly like pointers except they are 
always implicitly dereferenced:

int y = 123;
int* x1 = y; // *x1 == y   x1 == y
int x2 = y;  //  x2 == y  x2 == y

In fact, with one small tweak, C++ could have entirely eliminated the need for 
pointers (except array pointers), and references could have been used for 
everything except arrays. The reason references cannot replace pointers is that the 
pointer--the true identity of a reference--is immutable. But that's easily fixable 
though, by defining x2 as an lvalue:


x1 = z;
x2 = z; // Aha! We've changed the pointer inside the reference

If the second line were legal, then references could do everything that pointers could do; in that case I think that, for 
consistency, people would have eventually standardized on using references for everything that doesn't require pointer arithmetic 
(i.e. arrays). Instead we have this situation where some functions take (non-const) T and others take T*, so sometimes you 
have to call functions with foo and other times it's just foo, and the presence or absence of 
 doesn't signify anything important (for example, it doesn't tell you whether the callee mutates foo 
or not)


This is orthogonal, and I don't want to make that change. I like the 
explicitness of pointers.



It seems to me that the majority of languages have recognized that references are easier to work with 
than pointers, and not just because you can write foo.f() instead of 
foo-f(). That is, I don't think auto-deref (where foo.f() means (*foo).f()) is enough 
to eliminate the pain of working with pointers instead of references.


This is because in most languages all object types are reference types 
and they rely on a GC, following Lisp.



Would it help to define ~T, T and @T as reference types rather than pointer 
types? I'm sure there are some obvious objections, but perhaps the problems could 
be ironed out by someone with a better grasp of Rust.


Doesn't work with custom smart pointers.


I'd also like to comment on the removal of move. While I recognize explicit moves everywhere might be 
inconvenient, I have noticed that newbies on the list (including myself) are often confused by them. Would a compromise 
be in order, in which moves are implicit except when passing parameters to methods? I like Bill Byers' suggestion for 
call-site parameters of the form move x, mut x and just x for implicit copy / 
borrow. Patrick mentioned the annoyance of writing

  let move x = move foo(move y);

but


  let x = foo(move y);

doesn't sound so onerous, and it says something important about foo() that 
someone reading the code might not realize.


-1. It'd be inconsistent to require it only in parameter position.

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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Kevin Ballard
On Nov 20, 2013, at 8:52 AM, Corey Richardson co...@octayn.net wrote:

 I do, and I agree a lot with Niko's arguments from the meeting. I
 agree that * is a bit ugly, but I prefer the ugly syntax to the
 ambiguity. I don't find Kevin's argument particularly convincing;
 those changes can make your code fail to compile, but *not* to
 transparently behave differently (simply by changing the types of the
 args).

Sure they can.

fn foo(_: int) {}
let mut x = 0;
foo(x);
x -= 1;
println!({}, x);

prints -1. Change the first line to

fn foo(_: uint) {}

and now this prints 18446744073709551615 (on my 64-bit machine).

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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Vadim
On Wed, Nov 20, 2013 at 10:27 AM, Patrick Walton pcwal...@mozilla.comwrote:

 On 11/20/13 10:23 AM, David Piepgrass wrote:


 snip


  It seems to me that the majority of languages have recognized that
 references are easier to work with than pointers, and not just because you
 can write foo.f() instead of foo-f(). That is, I don't think
 auto-deref (where foo.f() means (*foo).f()) is enough to eliminate the pain
 of working with pointers instead of references.


 This is because in most languages all object types are reference types and
 they rely on a GC, following Lisp.


But const references work out pretty well in C++, and it'd be hard to
accuse C++ of relying on GC.



 Would it help to define ~T, T and @T as reference types rather than
 pointer types? I'm sure there are some obvious objections, but perhaps the
 problems could be ironed out by someone with a better grasp of Rust.


 Doesn't work with custom smart pointers.


I'm sure something can be worked out for smart pointers with the help of
some kind of AutoDeref trait.



I'd also like to comment on the removal of move. While I recognize
 explicit moves everywhere might be inconvenient, I have noticed that
 newbies on the list (including myself) are often confused by them. Would a
 compromise be in order, in which moves are implicit except when passing
 parameters to methods? I like Bill Byers' suggestion for call-site
 parameters of the form move x, mut x and just x for implicit copy /
 borrow. Patrick mentioned the annoyance of writing

   let move x = move foo(move y);

 but


   let x = foo(move y);

 doesn't sound so onerous, and it says something important about foo()
 that someone reading the code might not realize.


 -1. It'd be inconsistent to require it only in parameter position.


Well, it *would* be kind of consistent with Rust's policy type inference
everywhere, except in function parameters.

Also, - look at this thread - people are concerned about ambiguous
mutability and moved-ness properties of function parameters, not about
ambiguity of the level of indirection.

I think that reference semantics for pointers combined with foo(mut x);
foo(move y)'; would address the former while not introducing more syntax
noise required to disambiguate the latter.

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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Niko Matsakis
On Wed, Nov 20, 2013 at 11:23:57AM -0700, David Piepgrass wrote:
 I'm wondering something. Have the Rust developers considered the
 possibility of using references instead of pointers? It seems to me
 that this would eliminate a lot of the need for autoderef. Now I'm
 not well-equipped to talk about Rust (some of the rules I am totally
 ignorant about, e.g. I know rust has a ref keyword but the tutorial
 does not mention it) so let me talk about C++ instead.

I've thought about it, yes. When first designing the system, we were
aiming for C-like semantics, which expose the underlying machinery of
the computer more clearly. But I've since come to appreciate C++
references as well, though they are the poster child for creating
invisible links between caller and callee.

It's not entirely clear to me how C++ like references combine with
type inference, particularly the H-M-like variant we are using now.
In C++, there is no *operator* to create (or dereference) a reference,
instead it is driven implicitly by type coercion (the very topic under
discussion, in fact). Since C++ has such limited inference, this works
out reasonably OK, but in Rust I imagine it'd be more troublesome.

For example:

let arr = ~[1, 2, 3];
let v = ~[];
v.push(arr[0]);
v.push(arr[1]);
v.push(arr[2]);

I could legally infer the type of `v` to be either `~[int]` or
`~[int]` here, the meaning is very different, and there is no real
way for the user to be explicit about the difference other than
supplying some type annotations.

We're not immune to this. Our own coercions also potentially interact
with inference. They are relatively limited, though, and we tend to
have explicit operators as well, which helps. [1]



Niko

[1] See the interactions with inference section in my post. :)


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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Tommi
On 2013-11-20, at 18:27, Patrick Walton pcwal...@mozilla.com wrote:

 On 11/19/13 9:42 PM, Tommi wrote:
 Our problem is that, given let arg: ~A;, seeing only foo(arg) in code
 doesn't tell us whether arg is moved or borrowed. The proposed solution
 is that auto-borrowing in that context would be deprecated and thus
 would require an explicit borrowing: foo(*arg). Now, given that it
 seems that the upcoming UFCS would simply re-write arg.foo() to
 foo(arg), it would mean that seeing only arg.foo() in code doesn't tell
 us whether arg is moved or borrowed. Thus, the proposed solution would
 fix only half of the problem.
 
 Again, I don't see this as an argument against the proposal. The dot operator 
 is always magical. Magic on one place doesn't justify magic everywhere.
 
 Patrick
 

The goal of the proposal is to disambiguate code by forcing programmers to 
write foo(*arg) instead of foo(arg). But I claim that the proposal will at 
least partly fail to achieve that goal because programmers will simply resort 
to writing arg.foo() rather than foo(*arg), and we finish where we started.___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Tommi
While I'm trying to argue why the proposed solution is not a full solution to 
the proposed problem, I don't even think that the proposed problem is a 
problem. Here's why: if you make a call foo(arg) and never use arg after that, 
then you don't care if arg gets moved or borrowed. And if you try to use arg 
afterwards and foo did in fact move it previously, then your IDE is going to 
tell you about it by drawing a red squiggly line under that incorrect use of 
arg.___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Tim Kuehn
This strikes me as a good point. I think the incongruity this would create
between functions and methods -- along with the additional syntactic burden
-- could lead to the use of functions feeling second class in some sense.
Also, how would static methods be treated?

Cheers,
Tim


On Wed, Nov 20, 2013 at 8:47 PM, Tommi rusty.ga...@icloud.com wrote:

 On 2013-11-20, at 18:27, Patrick Walton pcwal...@mozilla.com wrote:

 On 11/19/13 9:42 PM, Tommi wrote:

 Our problem is that, given let arg: ~A;, seeing only foo(arg) in code
 doesn't tell us whether arg is moved or borrowed. The proposed solution
 is that auto-borrowing in that context would be deprecated and thus
 would require an explicit borrowing: foo(*arg). Now, given that it
 seems that the upcoming UFCS would simply re-write arg.foo() to
 foo(arg), it would mean that seeing only arg.foo() in code doesn't tell
 us whether arg is moved or borrowed. Thus, the proposed solution would
 fix only half of the problem.


 Again, I don't see this as an argument against the proposal. The dot
 operator is always magical. Magic on one place doesn't justify magic
 everywhere.

 Patrick


 The goal of the proposal is to disambiguate code by forcing programmers to
 write foo(*arg) instead of foo(arg). But I claim that the proposal will
 at least partly fail to achieve that goal because programmers will simply
 resort to writing arg.foo() rather than foo(*arg), and we finish where
 we started.

 ___
 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] Removing some autoref magic

2013-11-20 Thread Ziad Hatahet
What about @/Gc types then? You could still potentially reuse them.

--
Ziad


On Wed, Nov 20, 2013 at 5:58 PM, Tommi rusty.ga...@icloud.com wrote:

 While I'm trying to argue why the proposed solution is not a full solution
 to the proposed problem, I don't even think that the proposed problem is a
 problem. Here's why: if you make a call foo(arg) and never use arg after
 that, then you don't care if arg gets moved or borrowed. And if you try
 to use arg afterwards and foo did in fact move it previously, then your
 IDE is going to tell you about it by drawing a red squiggly line under that
 incorrect use of arg.

 ___
 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] Removing some autoref magic

2013-11-20 Thread Ziad Hatahet
On Wed, Nov 20, 2013 at 5:58 PM, Tommi rusty.ga...@icloud.com wrote:

 Here's why: if you make a call foo(arg) and never use arg after that,
 then you don't care if arg gets moved or borrowed. And if you try to use
 arg afterwards and foo did in fact move it previously, then your IDE is
 going to tell you about it by drawing a red squiggly line under that
 incorrect use of arg.


This is from the point of view of the person writing the code. What about
someone reading the code? He/she would either have to go through the
remainder of the function/scope to make sure that `arg` was not being used
(if it were, then it was a borrow, otherwise, it could have been either a
borrow or a move); or they would have to look at the signature of `foo()`;
as opposed to just being able to tell right there at the call site.

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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Kevin Ballard
On Nov 20, 2013, at 6:21 PM, Ziad Hatahet hata...@gmail.com wrote:

 On Wed, Nov 20, 2013 at 5:58 PM, Tommi rusty.ga...@icloud.com wrote:
 Here's why: if you make a call foo(arg) and never use arg after that, then 
 you don't care if arg gets moved or borrowed. And if you try to use arg 
 afterwards and foodid in fact move it previously, then your IDE is going to 
 tell you about it by drawing a red squiggly line under that incorrect use of 
 arg.
 
 
 This is from the point of view of the person writing the code. What about 
 someone reading the code? He/she would either have to go through the 
 remainder of the function/scope to make sure that `arg` was not being used 
 (if it were, then it was a borrow, otherwise, it could have been either a 
 borrow or a move); or they would have to look at the signature of `foo()`; as 
 opposed to just being able to tell right there at the call site.

Why does the reader particularly care? Presumably the code compiles (otherwise 
I have to ask why they're reading broken code, which is broken in a way that 
the compiler would trivially explain), so either it's moved and the arg isn't 
used again, or it's borrowed. It only really matters if the reader wants to 
subsequently modify the code, at which point they're now the person writing the 
code. And we get back to Tommi's point that the compiler (or, ideally, an IDE) 
will tell you if you try and use a moved value.

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


Re: [rust-dev] Removing some autoref magic

2013-11-20 Thread Tommi
On 2013-11-21, at 4:16, Ziad Hatahet hata...@gmail.com wrote:

 What about @/Gc types then? You could still potentially reuse them.
 
 --
 Ziad
 
 
 On Wed, Nov 20, 2013 at 5:58 PM, Tommi rusty.ga...@icloud.com wrote:
 While I'm trying to argue why the proposed solution is not a full solution to 
 the proposed problem, I don't even think that the proposed problem is a 
 problem. Here's why: if you make a call foo(arg) and never use arg after 
 that, then you don't care if arg gets moved or borrowed. And if you try to 
 use arg afterwards and foo did in fact move it previously, then your IDE is 
 going to tell you about it by drawing a red squiggly line under that 
 incorrect use of arg.
 

Garbage collected variables are owned by the runtime and the programmer cannot 
move (change the ownership of) them.

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


Re: [rust-dev] Removing some autoref magic

2013-11-19 Thread Alex Crichton
Additionally, we discussed this today at our weekly meeting, and the
minutes can be found here:
https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-11-19#autoderef
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Removing some autoref magic

2013-11-19 Thread Kevin Ballard
In general, I’m not a fan of *, and I like auto-borrowing (autoref sounds like 
it turns T into T, not ~T into T). I understand the arguments to get rid of 
it though.

BTW, you said that the current proposal still includes autoref for function 
invocation. That sounds to me like autoref would still apply to x in foo(x). Is 
there something else you mean by that?

As I see it, the two interesting cases to consider for removing it are:

1. let x = ~Foo; foo(x); // looks like it moves x when it just borrows it

2. let mut a = ~[ … ]; sort(a); // mutates a

To me, the second case seems pretty clear that it shouldn’t auto-borrow a ~T to 
a mut T, and instead require sort(mut *a). It’s pretty ugly, but it makes it 
clear what’s going on. This case isn’t particularly common, which is why losing 
autoref isn’t very tragic.

The first case is the most common case, and it seems a shame to require *x 
everywhere. I understand the argument that it looks like x is moved until you 
read the function signature of foo(), but I’m not convinced that’s important 
enough to uglify the code. Arguably, you already have to know what foo() does 
to understand what the code is doing.

The basic argument, as I see it, is that the type signature of foo() shouldn’t 
change how the calling code treats its argument. If foo() changed from `fn 
foo(_: T)` to `fn foo(_: ~T)` then `x` would start being moved instead of 
borrowed, which could cause errors in subsequent code in the caller.

But the problem with this argument is that the type signature of foo() already 
changes how the calling code treats its argument, in a fashion that will 
surface errors in later code rather than at the call site. Notably, if the 
argument is not fully constrained to a specific type by the time foo(x) is 
called, it will further constrain the type that may not cause a problem until 
later. For example:

fn foo(_: uint);
fn bar(_: uint);

let x = 1;
foo(x);
bar(x);

This compiles just fine, but if foo() changes its argument to `int`, then the 
call to bar() will fail with a type error. More complex situations can be 
created using generic functions as well.

In the case of autoref, the question is whether the value will be moved, rather 
than the type of the value, which is a slightly different issue but I’m not 
convinced it’s different enough that it needs to be specially addressed.

The other problem with this is that, even with autoref removed, you can still 
hit the same problem of a seemingly-benign change elsewhere causing a compiler 
error in your code. Namely, if a struct has no destructor, and you rely on the 
ability to implicitly copy it (e.g. calling bar(x) where foo is fn bar(_: T)), 
then adding a destructor to the struct will cause your code to fail to compile, 
in just the same way that foo changing from `fn foo(_: T)` to `fn foo(_: ~T)` 
will today.

Overall, there just doesn’t seem to me to be a compelling reason to remove the 
ability to auto-borrow ~T into T. Removing the ability to auto-borrow ~T into 
mut T is more sensible though.

FWIW, a lot of why I like auto-borrowing is actually due to auto-slicing of 
~[T] into [T] and ~str into str. But I assume that when (if) DST happens, 
auto-slicing will just be a case of auto-borrowing. And until that happens I’d 
really like to avoiding having to say foo(v.as_slice()).

-Kevin

On Nov 19, 2013, at 2:08 PM, Alex Crichton a...@crichton.co wrote:

 Hello rust-dev!
 
 Everyone's had their fair share of issues with autoref and autoderef,
 and it's worth considering removing certain portions of it from the
 compiler. The discussion around this has been rooted in the past, but
 has recently been brought up as part of
 https://github.com/mozilla/rust/issues/10504.
 
 The current proposal is to remove all autoref except for function
 invocations and indexing operations. The method of creating T from ~T
 would be `let foo: T = foo` or `*foo`. Vectors and strings can't
 currently benefit from the `*foo` syntax, but they will hopefully be
 able to do such once DST lands. In the meantime coercion via type
 ascription will work and they also have `as_slice` methods.
 
 There are a few reasons backing this proposal:
 
 1. It's inconsistent to have magical autoref in some places, but not
 in other places.
 2. The camp of less compiler magic is better can fly their flag over
 this change.
 3. Code readability does not necessarily benefit from autoref on arguments:
 
  let a = ~Foo;
  foo(a); // reading this code looks like it moves `a`
  fn foo(_: Foo) {} // ah, nevermind, it doesn't move `a`!
 
  let mut a = ~[ ... ];
  sort(a); // not only does this not move `a`, but it mutates it!
 
 The basic idea is that reasoning about code is no longer a local
 function decision, but rather you must understand all the pointer-ness
 of the called signatures to understand when a move happens or not.
 With no autoref, the code would look like
 
  let a = ~Foo;
  foo(*a); // clearly not passing by value
 
  let mut 

Re: [rust-dev] Removing some autoref magic

2013-11-19 Thread Ziad Hatahet
 Personally I would prefer if  in Rust worked similar to const T in c++

In that case, you would not be able to tell whether a function argument was
passed by value or by reference. I actually like this feature about Rust
(C# has it too with the `ref` keyword).

--
Ziad


On Tue, Nov 19, 2013 at 4:54 PM, Vadim vadi...@gmail.com wrote:

 So why did Rust adopt auto-moving instead of explicit moving?   If the
 second example had to be written as foo(move a) there would be no
 confusion.   The and the third example should arguably be sort(mut
 a.as_mut_slice()).

 Personally I would prefer if  in Rust worked similar to const T in c++
 (i.e. for most intents and purposes you can treat a reference as a value),
 otherwise half of the arguments on each function call will have to be
 adorned with ampersands.

 Can we have it such that foo(a) would be guaranteed to not mutate or move
 a and require mut or move prefix otherwise?


 ___
 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] Removing some autoref magic

2013-11-19 Thread Vadim
If the function is not going to mutate it, I don't really care if it's
by-ref or by-value.   That's why I said const T, not T.   Well,
except for the case when a function caches a reference to something which I
later mutate.   But borrow checking will prevent that.

I would also be totally fine with letting the compiler figure out how
immutable arguments are passed (based on data type size, existence of
destructors, and whatnot).  This might not be the best idea for binary
compatibility of public APIs, but I don't see why it can't be done with
crate-private functions.




On Tue, Nov 19, 2013 at 5:07 PM, Ziad Hatahet hata...@gmail.com wrote:

  Personally I would prefer if  in Rust worked similar to const T in c++

 In that case, you would not be able to tell whether a function argument
 was passed by value or by reference. I actually like this feature about
 Rust (C# has it too with the `ref` keyword).

 --
 Ziad


 On Tue, Nov 19, 2013 at 4:54 PM, Vadim vadi...@gmail.com wrote:

 So why did Rust adopt auto-moving instead of explicit moving?   If the
 second example had to be written as foo(move a) there would be no
 confusion.   The and the third example should arguably be sort(mut
 a.as_mut_slice()).

 Personally I would prefer if  in Rust worked similar to const T in c++
 (i.e. for most intents and purposes you can treat a reference as a value),
 otherwise half of the arguments on each function call will have to be
 adorned with ampersands.

 Can we have it such that foo(a) would be guaranteed to not mutate or move
 a and require mut or move prefix otherwise?


 ___
 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] Removing some autoref magic

2013-11-19 Thread Ben Kloosterman
While i like auto magic eg you could let region analysis work out the
pointer type , borrowed pointers etc  ,however you need to be very careful
. C# uses ref  but autoboxing is a major issue , you dont know when the
struct is boxed ( there are some places besides the obvious virt call ) and
then you incur boxing costs  defeating the whole point of value types .
 The vast majority of C# developers only use structs for a few corner cases
eg a type holding a few values  ( many dont use value types at all) , they
could go further but often it will get boxed somewhere and kill the
benefits so why go through the hassle.

Ben


On Wed, Nov 20, 2013 at 9:35 AM, Vadim vadi...@gmail.com wrote:

 If the function is not going to mutate it, I don't really care if it's
 by-ref or by-value.   That's why I said const T, not T.   Well,
 except for the case when a function caches a reference to something which I
 later mutate.   But borrow checking will prevent that.

 I would also be totally fine with letting the compiler figure out how
 immutable arguments are passed (based on data type size, existence of
 destructors, and whatnot).  This might not be the best idea for binary
 compatibility of public APIs, but I don't see why it can't be done with
 crate-private functions.




 On Tue, Nov 19, 2013 at 5:07 PM, Ziad Hatahet hata...@gmail.com wrote:

  Personally I would prefer if  in Rust worked similar to const T in c++

 In that case, you would not be able to tell whether a function argument
 was passed by value or by reference. I actually like this feature about
 Rust (C# has it too with the `ref` keyword).

 --
 Ziad


 On Tue, Nov 19, 2013 at 4:54 PM, Vadim vadi...@gmail.com wrote:

 So why did Rust adopt auto-moving instead of explicit moving?   If the
 second example had to be written as foo(move a) there would be no
 confusion.   The and the third example should arguably be sort(mut
 a.as_mut_slice()).

 Personally I would prefer if  in Rust worked similar to const T in c++
 (i.e. for most intents and purposes you can treat a reference as a value),
 otherwise half of the arguments on each function call will have to be
 adorned with ampersands.

 Can we have it such that foo(a) would be guaranteed to not mutate or
 move a and require mut or move prefix otherwise?


 ___
 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


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


Re: [rust-dev] Removing some autoref magic

2013-11-19 Thread Tommi
On 2013-11-20, at 1:40, Benjamin Striegel ben.strie...@gmail.com wrote:

 If autoref still happens on methods, does this mean that you'd be able to get 
 around the need to do:
 
 sort(mut *foo);
 
 ...by turning it into a method?
 
 foo.sort();

I like how your argument nudges this whole discussion a few inches to the left. 
Now we see that disallowing auto-borrowing from regular function arguments 
doesn't buy us anything unless we also disallow it from the target of method 
invocation syntax (dot notation). And that's obviously assuming the upcoming 
UFCS feature. I doubt that anyone would like to be writing 
(*foo).call_method() all day long.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Removing some autoref magic

2013-11-19 Thread Patrick Walton

On 11/19/13 7:43 PM, Tommi wrote:

I like how your argument nudges this whole discussion a few inches to
the left. Now we see that disallowing auto-borrowing from regular
function arguments doesn't buy us anything unless we also disallow it
from the target of method invocation syntax (dot notation). And
that's obviously assuming the upcoming UFCS feature. I doubt that
anyone would

like to be writing (*foo).call_method() all day long.

Magic in one part of the language isn't equivalent to magic everywhere 
in the language. The dot operator is already magical in several ways: it 
autoderefs for fields and searches through all traits in scope. This 
proposal would confine the magic to that operator and that operator 
alone, preventing it from leaking out into other parts of the language.


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


Re: [rust-dev] Removing some autoref magic

2013-11-19 Thread Tommi
On 2013-11-20, at 6:24, Patrick Walton pcwal...@mozilla.com wrote:

 On 11/19/13 7:43 PM, Tommi wrote:
 I like how your argument nudges this whole discussion a few inches to
 the left. Now we see that disallowing auto-borrowing from regular
 function arguments doesn't buy us anything unless we also disallow it
 from the target of method invocation syntax (dot notation). And
 that's obviously assuming the upcoming UFCS feature. I doubt that
 anyone would like to be writing (*foo).call_method() all day long.
 
 Magic in one part of the language isn't equivalent to magic everywhere in the 
 language. The dot operator is already magical in several ways: it autoderefs 
 for fields and searches through all traits in scope. This proposal would 
 confine the magic to that operator and that operator alone, preventing it 
 from leaking out into other parts of the language.
 
 Patrick
 

Yeah, my claim that it doesn't buy us anything stemmed from a misconception 
that arg.foo() could move arg, given let arg: ~A; and fn foo(x: ~A) {...}. I 
had already forgotten that Rust UFCS was specified differently from D's. To 
anyone not following, in D it would be a simple re-write to foo(arg) and, in 
Rust, to foo(arg).___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Removing some autoref magic

2013-11-19 Thread Tommi

On 2013-11-20, at 7:13, Tommi rusty.ga...@icloud.com wrote:

 Yeah, my claim that it doesn't buy us anything stemmed from a misconception 
 that arg.foo() could move arg, given let arg: ~A; and fn foo(x: ~A) {...}. I 
 had already forgotten that Rust UFCS was specified differently from D's. To 
 anyone not following, in D it would be a simple re-write to foo(arg) and, in 
 Rust, to foo(arg).

Scratch that. I seem to have different things mixed up now. I found this ticket 
https://github.com/mozilla/rust/issues/6974 again and it seems I should stand 
by my initial argument. Let me explain my argument again:

Our problem is that, given let arg: ~A;, seeing only foo(arg) in code doesn't 
tell us whether arg is moved or borrowed. The proposed solution is that 
auto-borrowing in that context would be deprecated and thus would require an 
explicit borrowing: foo(*arg). Now, given that it seems that the upcoming UFCS 
would simply re-write arg.foo() to foo(arg), it would mean that seeing only 
arg.foo() in code doesn't tell us whether arg is moved or borrowed. Thus, the 
proposed solution would fix only half of the problem.___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev