Re: [rust-dev] PSA: ~string is probably not what you want

2013-05-01 Thread Gábor Lehel
On Tue, Apr 30, 2013 at 9:22 PM, Graydon Hoare gray...@mozilla.com wrote:

 On 30/04/2013 11:26 AM, Gábor Lehel wrote:

  Couldn't this be relaxed? In other words allow dynamically sized `str`
 as a type (and perhaps similarly for other dynamically sized types), but
 prohibit those things specifically which would be problematic, i.e.
 using it in ways that would require knowing its size?


 This option was considered at ... great length, a year ago during the
 vector-reform conversations.

 https://mail.mozilla.org/pipermail/rust-dev/2012-April/001742.html
 https://mail.mozilla.org/pipermail/rust-dev/2012-April/001772.html
 https://mail.mozilla.org/pipermail/rust-dev/2012-June/001951.html
 https://mail.mozilla.org/pipermail/rust-dev/2012-July/002114.html

 I'm not sure anyone ever reduced those threads to their essence, but
 re-reading them I think I can articulate the fundamental difficulty with
 what you're suggesting:

   - Any object has a real size. Some sizes are statically known,
 some must be discovered dynamically (by reading a size field
 or carrying a size value in a (ptr,size) pair)

   - When T is static-size, T and ~T and @T should be 1-word
 pointers. The compiler knows the size.

   - To operate on a vector of statically-unknown size, you
 need to get its dynamically-known size from somewhere.
 This means pointers to vectors need to carry bounds.

   - So ~[] and @[] and [] are not the same representation as
 ~T, @T and T in general. They have to have a size stuck
 on them somewhere.

   - We want to be able to take sub-slices and have slices that
 point to fixed-size vectors in C structs. This means
 slices can't have their length in the pointee, and have to be
 (ptr,len) pairs.

 So about the only wiggle room away from where we are now is that we might
 be able to make ~[] represented by (ptr,len) pairs too, like slices are,
 rather than 1 ptr that points to a [len,data...] buffer. But it's not clear
 if that would buy us anything. Maybe a bit more genericity in impls, though
 I don't know how; Niko might. There might be a bit more room for
 improvement here, but it's an _extremely_ constrained space to work in.

 -Graydon


Thanks for the explanation! That makes a lot of sense.

I also just read Niko's blog post, and I'm not sure which thread to reply
in (or who to reply to), but I guess I'll do it here. Niko's message here
beforehand was kind of expectations-downplaying, but reading the blog post,
his proposed scheme seems to allow more or less the same as what I was
asking about here (perhaps minus the user-defined dynamically sized types,
but that was icing).

So *if* the plan ends up working out, then taking the second part of my
earlier proposal:

 You might also have a rule whereby dereferencing a variable when the
 result would be a dynamically-sized type is allowed *if* the result is
 immediately borrowed. Then instead of `impl Eq for {@str, ~str, str}`,
 you would have just `impl Eq for str`, and if you want to compare an
 ~str you dereference it.

Would that work? Would it be a good solution?

-- 
Your ship was destroyed in a monadic eruption.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] PSA: ~string is probably not what you want

2013-05-01 Thread Niko Matsakis
On Wed, May 01, 2013 at 02:39:12PM +0200, Gábor Lehel wrote:
 I also just read Niko's blog post, and I'm not sure which thread to reply
 in (or who to reply to), but I guess I'll do it here. Niko's message here
 beforehand was kind of expectations-downplaying, but reading the blog post,
 his proposed scheme seems to allow more or less the same as what I was
 asking about here (perhaps minus the user-defined dynamically sized types,
 but that was icing).

Yeah, I wasn't sure how well that idea of changing the representation
for all vecs/strings would work out, but then in the process of
writing the post I decided it worked out quite well. It was an idea I
first had last summer when we were hashing this out the first time,
and have been meaning to chew on for some time, so I'm glad we had
this thread on the mailing list to bring it back to my mind.

 So *if* the plan ends up working out, then taking the second part of my
 earlier proposal:
 
  You might also have a rule whereby dereferencing a variable when the
  result would be a dynamically-sized type is allowed *if* the result is
  immediately borrowed. Then instead of `impl Eq for {@str, ~str, str}`,
  you would have just `impl Eq for str`, and if you want to compare an
  ~str you dereference it.
 
 Would that work? Would it be a good solution?

I believe that would be the plan, yes. Most of these 
apply-to-almost-everything
traits, like `Eq` or `Ord`, could be implemented in a similar fashion.

I'm not sure what problem you are proposing this as a solution *for*,
though.  Do you mean the problem of comparing strings using `==`?

I suppose it is true that under this proposal you could write

let str1: ~str = ~hi;
let str2: str = hi;
*str1 == *str2

and it would work fine. That is a nice side-effect I hadn't
considered.

*An aside:* Note that dereferencing a pointer to an unsized object is
only allowed in an lvalue context (that is, when we are taking its
address):

let str1: ~str = ~hi;
let foo = *str1; // ERROR
let bar = *str1; // OK

Here, `foo` is an error because `*str1` is being evaluated in an
rvalue context, but `bar` is fine, because `*str1` is being evaluted
in an lvalue context. In the case of `==`, this works out because the
arguments to overloaded operators are always passed by reference.

*A further aside:* don't be misled by my use of the term
lvalue context into thinking that a program like this would
be legal:

let mut str1: ~str = ~Hello;
*str1 = World; // ERROR

This is illegal because assigning to an lvalue of unsized type is
illegal, even though `*str1` appears in an lvalue context.



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


Re: [rust-dev] PSA: ~string is probably not what you want

2013-05-01 Thread Gábor Lehel
On Wed, May 1, 2013 at 4:50 PM, Niko Matsakis n...@alum.mit.edu wrote:

 On Wed, May 01, 2013 at 02:39:12PM +0200, Gábor Lehel wrote:

  So *if* the plan ends up working out, then taking the second part of my
  earlier proposal:
 
   You might also have a rule whereby dereferencing a variable when the
   result would be a dynamically-sized type is allowed *if* the result is
   immediately borrowed. Then instead of `impl Eq for {@str, ~str, str}`,
   you would have just `impl Eq for str`, and if you want to compare an
   ~str you dereference it.
 
  Would that work? Would it be a good solution?

 I believe that would be the plan, yes. Most of these
 apply-to-almost-everything
 traits, like `Eq` or `Ord`, could be implemented in a similar fashion.

 I'm not sure what problem you are proposing this as a solution *for*,
 though.  Do you mean the problem of comparing strings using `==`?


Yeah. Which was the original topic of this thread... :)



 I suppose it is true that under this proposal you could write

 let str1: ~str = ~hi;
 let str2: str = hi;
 *str1 == *str2

 and it would work fine. That is a nice side-effect I hadn't
 considered.


Right. That was the intent. And similarly(?) for comparing against string
literals. (Though I'm not completely clear about when auto-borrowing does
or doesn't happen, and how that would interact with this.)



 *An aside:* Note that dereferencing a pointer to an unsized object is
 only allowed in an lvalue context (that is, when we are taking its
 address):

 let str1: ~str = ~hi;
 let foo = *str1; // ERROR
 let bar = *str1; // OK

 Here, `foo` is an error because `*str1` is being evaluated in an
 rvalue context, but `bar` is fine, because `*str1` is being evaluted
 in an lvalue context. In the case of `==`, this works out because the
 arguments to overloaded operators are always passed by reference.


Yep, that's what I was figuring. I'm not sure what lvalue context means
precisely -- it's not actually on the left hand side of anything here, and
the other example below where it *is* on the LHS is illegal -- but the
shape of things matches what I was expecting.



 *A further aside:* don't be misled by my use of the term
 lvalue context into thinking that a program like this would
 be legal:

 let mut str1: ~str = ~Hello;
 *str1 = World; // ERROR

 This is illegal because assigning to an lvalue of unsized type is
 illegal, even though `*str1` appears in an lvalue context.


Hmm. If I'm thinking right this is because the size of the string is stored
in the pointer, which, if the string gets changed behind its back, would
become invalid?





 regards,
 Niko




-- 
Your ship was destroyed in a monadic eruption.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-30 Thread Gábor Lehel
On Sun, Apr 28, 2013 at 8:14 PM, Patrick Walton pwal...@mozilla.com wrote:



  Is
  there some way to make it just work, no matter what kind of strings
  you're comparing?  Perhaps foo == (*x) would work, for example?

  That doesn't work, because it makes the dynamically sized `str` a type,
 which is incoherent. (It would lead to dynamically sized stack frames, or
 structs or enums with infinite size, and so on.)


Couldn't this be relaxed? In other words allow dynamically sized `str` as a
type (and perhaps similarly for other dynamically sized types), but
prohibit those things specifically which would be problematic, i.e. using
it in ways that would require knowing its size? I think this would
essentially mean no variables, members, or parameters of that type, but you
*could* use it as a type argument -- including to the various pointer type
constructors. You might also have a rule whereby dereferencing a variable
when the result would be a dynamically-sized type is allowed *if* the
result is immediately borrowed. Then instead of `impl Eq for {@str, ~str,
str}`, you would have just `impl Eq for str`, and if you want to compare
an ~str you dereference it.  Which seems logical to me, after all
ostensibly you want to compare the contents and not the pointer.

-- 
Your ship was destroyed in a monadic eruption.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-30 Thread Patrick Walton

On 4/30/13 11:26 AM, Gábor Lehel wrote:

Couldn't this be relaxed? In other words allow dynamically sized `str`
as a type (and perhaps similarly for other dynamically sized types), but
prohibit those things specifically which would be problematic, i.e.
using it in ways that would require knowing its size? I think this would
essentially mean no variables, members, or parameters of that type, but
you *could* use it as a type argument -- including to the various
pointer type constructors.


Unfortunately that doesn't work, because opaque type variables `T` can 
still be moved, including into the local stack frame.


Patrick

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


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-30 Thread Gábor Lehel
On Tue, Apr 30, 2013 at 8:27 PM, Patrick Walton pwal...@mozilla.com wrote:

 On 4/30/13 11:26 AM, Gábor Lehel wrote:

 Couldn't this be relaxed? In other words allow dynamically sized `str`
 as a type (and perhaps similarly for other dynamically sized types), but
 prohibit those things specifically which would be problematic, i.e.
 using it in ways that would require knowing its size? I think this would
 essentially mean no variables, members, or parameters of that type, but
 you *could* use it as a type argument -- including to the various
 pointer type constructors.


  Unfortunately that doesn't work, because opaque type variables `T` can
 still be moved, including into the local stack frame.


This did actually occur to me while writing the previous, along with early
thoughts about what you could do about it, but I thought I wouldn't get too
far ahead of myself. My thought process so far has been:

- OK, so maybe you would need a new built-in trait to track it, say
StaticSized, which you would need if you want to do that kind of thing with
a type variable.

- But that's the *common* case. You would have to write StaticSized
everywhere! Clearly that's not viable.

- OK, so maybe there's a way to invert it? ...but that doesn't really make
any sense, after half a minute of reflection.

- What about inference? The compiler checks how the type parameter is used,
and if it's used in way that requires knowing its size, the compiler puts
an implicit must be statically sized constraint on it, after which
instantiating it with a dynamically sized type produces an error at the
point of instantiation. (Not having it be obvious in the source at the
point of declaration whether a type variable is allowed to be dynamically
sized would be an annoyance, but I think a minor one. In the generated
documentation it could maybe be indicated by italics, or their absence.)

So that's where I am right now. What about inference? (I recall reading
that co/contravariance is also handled by inference, but I don't know if
that has any parallels with this beyond the superficial.)

Another thing this might allow is user-defined dynamically sized types.
Putting a dynamically sized type as the last member of a struct or enum
variant would be allowed (as per the common C idiom), in which case the
struct or enum itself would be considered dynamically sized, and have the
same rules apply.

-- 
Your ship was destroyed in a monadic eruption.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-30 Thread Graydon Hoare

On 30/04/2013 11:26 AM, Gábor Lehel wrote:


Couldn't this be relaxed? In other words allow dynamically sized `str`
as a type (and perhaps similarly for other dynamically sized types), but
prohibit those things specifically which would be problematic, i.e.
using it in ways that would require knowing its size?


This option was considered at ... great length, a year ago during the 
vector-reform conversations.


https://mail.mozilla.org/pipermail/rust-dev/2012-April/001742.html
https://mail.mozilla.org/pipermail/rust-dev/2012-April/001772.html
https://mail.mozilla.org/pipermail/rust-dev/2012-June/001951.html
https://mail.mozilla.org/pipermail/rust-dev/2012-July/002114.html

I'm not sure anyone ever reduced those threads to their essence, but 
re-reading them I think I can articulate the fundamental difficulty with 
what you're suggesting:


  - Any object has a real size. Some sizes are statically known,
some must be discovered dynamically (by reading a size field
or carrying a size value in a (ptr,size) pair)

  - When T is static-size, T and ~T and @T should be 1-word
pointers. The compiler knows the size.

  - To operate on a vector of statically-unknown size, you
need to get its dynamically-known size from somewhere.
This means pointers to vectors need to carry bounds.

  - So ~[] and @[] and [] are not the same representation as
~T, @T and T in general. They have to have a size stuck
on them somewhere.

  - We want to be able to take sub-slices and have slices that
point to fixed-size vectors in C structs. This means
slices can't have their length in the pointee, and have to be
(ptr,len) pairs.

So about the only wiggle room away from where we are now is that we 
might be able to make ~[] represented by (ptr,len) pairs too, like 
slices are, rather than 1 ptr that points to a [len,data...] buffer. But 
it's not clear if that would buy us anything. Maybe a bit more 
genericity in impls, though I don't know how; Niko might. There might be 
a bit more room for improvement here, but it's an _extremely_ 
constrained space to work in.


-Graydon

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


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-30 Thread Niko Matsakis
On Tue, Apr 30, 2013 at 12:22:15PM -0700, Graydon Hoare wrote:
 So about the only wiggle room away from where we are now is that we
 might be able to make ~[] represented by (ptr,len) pairs too, like
 slices are, rather than 1 ptr that points to a [len,data...] buffer.
 But it's not clear if that would buy us anything. Maybe a bit more
 genericity in impls, though I don't know how; Niko might. There
 might be a bit more room for improvement here, but it's an
 _extremely_ constrained space to work in.

I've been working on a blog post about this. I'm not yet sure if it
buys us anything. I'll try to finish that up and get it out. But
basically everything you said is true, particularly that last
sentence!


Niko

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


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-30 Thread Vadim
Hi Graydon,
How does Rust currently represent its' pointers to vectors?  Based on what
I've seen in the library, it seems that ~[T] and @[T] are plain pointers
(with size stored in the pointee), but [T] is a fat pointer, i.e. a
(ptr,len) pair.  Is this correct?


On Tue, Apr 30, 2013 at 12:22 PM, Graydon Hoare gray...@mozilla.com wrote:

 On 30/04/2013 11:26 AM, Gábor Lehel wrote:

  Couldn't this be relaxed? In other words allow dynamically sized `str`
 as a type (and perhaps similarly for other dynamically sized types), but
 prohibit those things specifically which would be problematic, i.e.
 using it in ways that would require knowing its size?


 This option was considered at ... great length, a year ago during the
 vector-reform conversations.

 https://mail.mozilla.org/**pipermail/rust-dev/2012-April/**001742.htmlhttps://mail.mozilla.org/pipermail/rust-dev/2012-April/001742.html
 https://mail.mozilla.org/**pipermail/rust-dev/2012-April/**001772.htmlhttps://mail.mozilla.org/pipermail/rust-dev/2012-April/001772.html
 https://mail.mozilla.org/**pipermail/rust-dev/2012-June/**001951.htmlhttps://mail.mozilla.org/pipermail/rust-dev/2012-June/001951.html
 https://mail.mozilla.org/**pipermail/rust-dev/2012-July/**002114.htmlhttps://mail.mozilla.org/pipermail/rust-dev/2012-July/002114.html

 I'm not sure anyone ever reduced those threads to their essence, but
 re-reading them I think I can articulate the fundamental difficulty with
 what you're suggesting:

   - Any object has a real size. Some sizes are statically known,
 some must be discovered dynamically (by reading a size field
 or carrying a size value in a (ptr,size) pair)

   - When T is static-size, T and ~T and @T should be 1-word
 pointers. The compiler knows the size.

   - To operate on a vector of statically-unknown size, you
 need to get its dynamically-known size from somewhere.
 This means pointers to vectors need to carry bounds.

   - So ~[] and @[] and [] are not the same representation as
 ~T, @T and T in general. They have to have a size stuck
 on them somewhere.

   - We want to be able to take sub-slices and have slices that
 point to fixed-size vectors in C structs. This means
 slices can't have their length in the pointee, and have to be
 (ptr,len) pairs.

 So about the only wiggle room away from where we are now is that we might
 be able to make ~[] represented by (ptr,len) pairs too, like slices are,
 rather than 1 ptr that points to a [len,data...] buffer. But it's not clear
 if that would buy us anything. Maybe a bit more genericity in impls, though
 I don't know how; Niko might. There might be a bit more room for
 improvement here, but it's an _extremely_ constrained space to work in.

 -Graydon

 __**_
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/**listinfo/rust-devhttps://mail.mozilla.org/listinfo/rust-dev

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


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-30 Thread Graydon Hoare

On 30/04/2013 2:03 PM, Vadim wrote:

Hi Graydon,
How does Rust currently represent its' pointers to vectors?  Based on
what I've seen in the library, it seems that ~[T] and @[T] are plain
pointers (with size stored in the pointee), but [T] is a fat pointer,
i.e. a (ptr,len) pair.  Is this correct?


Correct. And [T, ..N] is N copies of T laid out in memory as a 
not-pointer-indirect value.


-Graydon


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


[rust-dev] PSA: ~string is probably not what you want

2013-04-28 Thread Patrick Walton
Just thought I'd give the mailing list a heads up that ~string, 
besides being ugly, is generally inefficient: it allocates a string on 
the heap and frees it when it goes out of scope. There are no 
optimizations that eliminate the allocation.


If you need to compare a `~str` against a constant string, use .equiv():

use core::cmp::Equiv;

fn main() {
let x = ~foo;
if foo.equiv(x) {
println(yep);
}
}

This should admittedly be imported by default.

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


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-28 Thread Lee Braiden

On 28/04/13 18:45, Patrick Walton wrote:

If you need to compare a `~str` against a constant string, use .equiv():

use core::cmp::Equiv;

fn main() {
let x = ~foo;
if foo.equiv(x) {
println(yep);
}
}

This should admittedly be imported by default.


Really?  Strings can't just be compared with == ?  To be honest, that 
alone is almost enough to put me off the language -- not only is it ugly 
and unwieldy, but it suggests a lot of limitations in the language's 
memory model / type system / operator overloading, which would also make 
my own code ugly and unwieldy.


What's the problem with ==, or the difference with equiv(), exactly?  Is 
there some way to make it just work, no matter what kind of strings 
you're comparing?  Perhaps foo == (*x) would work, for example?



--
Lee

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


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-28 Thread Patrick Walton

On 4/28/13 10:57 AM, Lee Braiden wrote:

Really?  Strings can't just be compared with == ?  To be honest, that
alone is almost enough to put me off the language -- not only is it ugly
and unwieldy, but it suggests a lot of limitations in the language's
memory model / type system / operator overloading, which would also make
my own code ugly and unwieldy.

What's the problem with ==, or the difference with equiv(), exactly?


The problem is that `str` and `~str` are not the same type. We could 
change `Eq` so that it doesn't require the same type on the 
left-hand-side and the right-hand-side, but that would complicate the 
trait system quite a bit.


Currently, overloaded operators do not borrow. I guess we could change 
overloaded operators (or maybe just `==` and `!=`?) to try to borrow the 
left hand side and/or right hand side to make the types match. I think 
this is *probably* OK. However, we need to be careful, because it's 
exactly the kind of thing that could have unforeseen consequences.


Strings should be comparable with `==` without allocating is the kind 
of thing that is obviously true, but trying to do it without thinking 
carefully about the ramifications of borrowing in overloaded operators 
is problematic. We already have quite complex method lookup semantics 
exactly to make things like this just work, and it has fallout when you 
start having to get picky about how many dereferences you do.


To be honest, the tone of your message is a little frustrating, because 
you jumped on one thing that's not ideal (that the different types 
`~str` and `str` cannot be compared with `==`), said something 
inaccurate (that strings cannot be compared with `==`), and extrapolated 
it to the idea that Rust's type system is ugly and unwieldy. No, it's 
just that we need to think carefully about how to handle this one case.


 Is
 there some way to make it just work, no matter what kind of strings
 you're comparing?  Perhaps foo == (*x) would work, for example?

That doesn't work, because it makes the dynamically sized `str` a type, 
which is incoherent. (It would lead to dynamically sized stack frames, 
or structs or enums with infinite size, and so on.)


Patrick

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


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-28 Thread Daniel Micay
On Sun, Apr 28, 2013 at 1:57 PM, Lee Braiden leebr...@gmail.com wrote:
 On 28/04/13 18:45, Patrick Walton wrote:

 If you need to compare a `~str` against a constant string, use .equiv():

 use core::cmp::Equiv;

 fn main() {
 let x = ~foo;
 if foo.equiv(x) {
 println(yep);
 }
 }

 This should admittedly be imported by default.


 Really?  Strings can't just be compared with == ?  To be honest, that alone
 is almost enough to put me off the language -- not only is it ugly and
 unwieldy, but it suggests a lot of limitations in the language's memory
 model / type system / operator overloading, which would also make my own
 code ugly and unwieldy.

 What's the problem with ==, or the difference with equiv(), exactly?  Is
 there some way to make it just work, no matter what kind of strings you're
 comparing?  Perhaps foo == (*x) would work, for example?


 --
 Lee

Strings and vectors are special cased in the syntax, ~foo and
~(foo) aren't the same type. This issue is specific to the
string/vector implementations included in the language, it's a
non-issue with borrowed pointers or owned/shared boxes.

Eq doesn't take a type parameter for the right-hand side parameter,
 so if ~str is on the left-hand side the right-hand side has to be
~str too. Although a ~str can be borrowed as a slice so foo ==
~foo *will* work.

Eq *could* take a type parameter like Add, Sub, etc. - it just doesn't
right now.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-28 Thread heri16
It is very easy to create a language that is unwieldy, but hard to create something KISS simple that can be adopted, and that will be praised for its cleanliness and elegance.If the basic things are not simple, a language will be relegated to academia, and will not be as popular as hoped.We really need to take a look into this one, and come up with something workable. That won't be easy considering what Patrick has mentioned. Sent from my BlackBerry 10 smartphone.From: rust-dev-requ...@mozilla.orgSent: Monday, 29 April, 2013 3:00 AMTo: rust-dev@mozilla.orgReply To: rust-dev@mozilla.orgSubject: Rust-dev Digest, Vol 34, Issue 92Send Rust-dev mailing list submissions to	rust-dev@mozilla.orgTo subscribe or unsubscribe via the World Wide Web, visit	https://mail.mozilla.org/listinfo/rust-devor, via email, send a message with subject or body 'help' to	rust-dev-requ...@mozilla.orgYou can reach the person managing the list at	rust-dev-ow...@mozilla.orgWhen replying, please edit your Subject line so it is more specificthan "Re: Contents of Rust-dev digest..."Today's Topics:   1.  PSA: ~"string" is probably not what you want (Patrick Walton)   2. Re:  PSA: ~"string" is probably not what you want (Lee Braiden)   3. Re:  PSA: ~"string" is probably not what you want (Patrick Walton)   4. Re:  PSA: ~"string" is probably not what you want (Daniel Micay)--Message: 1Date: Sun, 28 Apr 2013 10:45:04 -0700From: Patrick Walton pwal...@mozilla.comTo: "rust-dev@mozilla.org" rust-dev@mozilla.orgSubject: [rust-dev] PSA: ~"string" is probably not what you wantMessage-ID: 517d6020.9080...@mozilla.comContent-Type: text/plain; charset=ISO-8859-1; format=flowedJust thought I'd give the mailing list a heads up that ~"string", besides being ugly, is generally inefficient: it allocates a string on the heap and frees it when it goes out of scope. There are no optimizations that eliminate the allocation.If you need to compare a `~str` against a constant string, use .equiv(): use core::cmp::Equiv; fn main() { let x = ~"foo"; if "foo".equiv(x) { println("yep"); } }This should admittedly be imported by default.Patrick--Message: 2Date: Sun, 28 Apr 2013 18:57:38 +0100From: Lee Braiden leebr...@gmail.comTo: rust-dev@mozilla.orgSubject: Re: [rust-dev] PSA: ~"string" is probably not what you wantMessage-ID: 517d6312.7030...@gmail.comContent-Type: text/plain; charset=ISO-8859-1; format=flowedOn 28/04/13 18:45, Patrick Walton wrote: If you need to compare a `~str` against a constant string, use .equiv(): use core::cmp::Equiv; fn main() { let x = ~"foo"; if "foo".equiv(x) { println("yep"); } } This should admittedly be imported by default.Really?  Strings can't just be compared with == ?  To be honest, that alone is almost enough to put me off the language -- not only is it ugly and unwieldy, but it suggests a lot of limitations in the language's memory model / type system / operator overloading, which would also make my own code ugly and unwieldy.What's the problem with ==, or the difference with equiv(), exactly?  Is there some way to make it just work, no matter what kind of strings you're comparing?  Perhaps "foo" == (*x) would work, for example?-- Lee--Message: 3Date: Sun, 28 Apr 2013 11:14:13 -0700From: Patrick Walton pwal...@mozilla.comTo: rust-dev@mozilla.orgSubject: Re: [rust-dev] PSA: ~"string" is probably not what you wantMessage-ID: 517d66f5.1020...@mozilla.comContent-Type: text/plain; charset=ISO-8859-1; format=flowedOn 4/28/13 10:57 AM, Lee Braiden wrote: Really?  Strings can't just be compared with == ?  To be honest, that alone is almost enough to put me off the language -- not only is it ugly and unwieldy, but it suggests a lot of limitations in the language's memory model / type system / operator overloading, which would also make my own code ugly and unwieldy. What's the problem with ==, or the difference with equiv(), exactly?The problem is that `str` and `~str` are not the same type. We could change `Eq` so that it doesn't require the same type on the left-hand-side and the right-hand-side, but that would complicate the trait system quite a bit.Currently, overloaded operators do not borrow. I guess we could change overloaded operators (or maybe just `==` and `!=`?) to try to borrow the left hand side and/or right hand side to make the types match. I think this is *probably* OK. However, we need to be careful, because it's exactly the kind of thing that could have 

Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-28 Thread Patrick Walton

On 4/28/13 12:45 PM, her...@gmail.com wrote:

It is very easy to create a language that is unwieldy, but hard to
create something KISS simple that can be adopted, and that will be
praised for its cleanliness and elegance.

If the basic things are not simple, a language will be relegated to
academia, and will not be as popular as hoped.

We really need to take a look into this one, and come up with something
workable. That won't be easy considering what Patrick has mentioned.


As Daniel pointed out, it isn't so bad. I didn't realize that we already 
borrow on the left hand side, so you can write:


fn main() {
let x = ~foo;
if foo == x {
println(yep);
}
}

We just need to borrow on the right hand side too, so that `x == foo` 
works. I can think of ways to do it; none are particularly pretty, but I 
suspect we could make it work. But the situation is not so dire now.


Patrick

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


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-28 Thread Simon Sapin

Le 28/04/2013 21:49, Patrick Walton a écrit :

As Daniel pointed out, it isn't so bad. I didn't realize that we already
borrow on the left hand side, so you can write:

  fn main() {
  let x = ~foo;
  if foo == x {
  println(yep);
  }
  }


Using `if constant == variable` rather than the reverse is sometimes 
called a Yoda condition and considered bad style, but that’s purely 
aesthetic. It’s still good that this works as expected.




We just need to borrow on the right hand side too, so that `x == foo`
works. I can think of ways to do it; none are particularly pretty, but I
suspect we could make it work. But the situation is not so dire now.


Is there a reason that both sides of the == operator should not behave 
the same? Like many operators == seems like it should be symmetric, 
ie. a == b are always the same for any a and b (and their types, 
presumably.)


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


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-28 Thread Mitch Skinner
On Sun, Apr 28, 2013 at 10:45 AM, Patrick Walton pwal...@mozilla.comwrote:

 If you need to compare a `~str` against a constant string, use .equiv():


I have some code where I'm trying to match an owned string against a set of
constant strings, and it's not clear to me how to take your advice there.

fn match_upper(to_match: str) - int {
match to_match.to_ascii().to_upper().to_str_ascii() {
~ABC = 1, ~DEF = 2, ~GHI = 3, _ = 0
}
}

Does each call to this function heap-allocate all the owned strings in the
match expression?  If so, how could I avoid that?  Is there a more
idiomatic way to do what I'm trying to do?

Thanks for the PSA,
Mitch
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-28 Thread Martin DeMello
In which case, would special-casing == and !=, as you mentioned
earlier, be a bad thing to do? (Sincere question; from a user pov it
would make sense, but I don't know whether it would make operator
overloading conceptually more ugly to have that special case in there)

martin

On Sun, Apr 28, 2013 at 12:49 PM, Patrick Walton pwal...@mozilla.com wrote:
 On 4/28/13 12:45 PM, her...@gmail.com wrote:

 It is very easy to create a language that is unwieldy, but hard to
 create something KISS simple that can be adopted, and that will be
 praised for its cleanliness and elegance.

 If the basic things are not simple, a language will be relegated to
 academia, and will not be as popular as hoped.

 We really need to take a look into this one, and come up with something
 workable. That won't be easy considering what Patrick has mentioned.


 As Daniel pointed out, it isn't so bad. I didn't realize that we already
 borrow on the left hand side, so you can write:

 fn main() {
 let x = ~foo;
 if foo == x {
 println(yep);
 }
 }

 We just need to borrow on the right hand side too, so that `x == foo`
 works. I can think of ways to do it; none are particularly pretty, but I
 suspect we could make it work. But the situation is not so dire now.

 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] PSA: ~string is probably not what you want

2013-04-28 Thread Jack Moffitt
 Really?  Strings can't just be compared with == ?  To be honest, that alone
 is almost enough to put me off the language -- not only is it ugly and
 unwieldy, but it suggests a lot of limitations in the language's memory
 model / type system / operator overloading, which would also make my own
 code ugly and unwieldy.

This kind of faux outrage isn't really constructive.

Most systems languages don't let you compare strings with ==. In C you
use str*cmp as == is pointer equality. This is also true in Java where
you must write `if (foo.equals(bar))`. It would certainly be nice to
follow in C++'s footsteps where std::strings are comparable with ==,
but I'm not sure it nullifies Rust's goals if this condition can't be
met.

Equality always seems to  be a mixed bag. In JavaScript you have ==
and ===. In Erlang you have == and =:=. In Java you have == and
.equals(). In Clojure you have = and ==. Lisps have all kinds of
things. In many cases you can end up with asymmetry that violates
people's mathemeatical expectations of equality (Clojure's == is only
commutative when used with two args, with 3 it gets slightly weird).

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


Re: [rust-dev] PSA: ~string is probably not what you want

2013-04-28 Thread Steve Klabnik
Ruby is one example of a language where == is not symmetric.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev