Re: [rust-dev] Many little questions while writing a Vector class

2013-02-21 Thread Niko Matsakis
You are correct that there is no deep relation.  I merely meant that the 
surface syntax looks similar.  Some of the same issues arise in both 
cases, but that has more to do with Rust's path resolution rules than 
anything else.



Niko

Gábor Lehel wrote:

On Thu, Feb 21, 2013 at 6:37 PM, Niko Matsakis  wrote:

There is some design work needed here.  In general, this seems to be related
to the desire for associated types [2].


Coming from Haskell, they seem like separate things to me (or rather
they're related only by them being extensions to the trait system). On
the one hand there's the desire to have types/traits parameterized on
things other than types: non-type template parameters in C++ parlance,
or type-level literals in Haskell (or type-level things of kind other
than * or k ->  k, in a broader sense). And on the other hand there's
the desire to have constants as members of a trait (type class).
That's Haskell 98, no extensions required. E.g. you have `class
Bounded a where minBound :: a; maxBound :: a`. (Haskell doesn't have a
distinction between nullary functions and simple values, so there's no
difference there between `static fn len() ->  uint` and `const len:
uint`.) But this is just a mapping from types to values, which is what
type classes do. Associated types come into the picture when you want
to map types to types.

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


Re: [rust-dev] Many little questions while writing a Vector class

2013-02-21 Thread Gábor Lehel
On Thu, Feb 21, 2013 at 6:37 PM, Niko Matsakis  wrote:
> There is some design work needed here.  In general, this seems to be related
> to the desire for associated types [2].

Coming from Haskell, they seem like separate things to me (or rather
they're related only by them being extensions to the trait system). On
the one hand there's the desire to have types/traits parameterized on
things other than types: non-type template parameters in C++ parlance,
or type-level literals in Haskell (or type-level things of kind other
than * or k -> k, in a broader sense). And on the other hand there's
the desire to have constants as members of a trait (type class).
That's Haskell 98, no extensions required. E.g. you have `class
Bounded a where minBound :: a; maxBound :: a`. (Haskell doesn't have a
distinction between nullary functions and simple values, so there's no
difference there between `static fn len() -> uint` and `const len:
uint`.) But this is just a mapping from types to values, which is what
type classes do. Associated types come into the picture when you want
to map types to types.

-- 
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] Many little questions while writing a Vector class

2013-02-21 Thread Niko Matsakis



Ashish Myles wrote:
So, I am to presume from your answer that there is no way to create 
class-associated constants?  Is this worth considering adding to Rust?


Rust does not, in fact, have classes.  However, what I think you are 
attempting to achieve is to have the ability to write generic code on 
some type T that is either Vector2 or Vector3, and then one could write 
T::len to reference the relevant constant.  The way to do this in Rust 
would probably be with a trait and a static fn:


trait VectorN {
static fn len() -> uint; // Eventually: just fn len() -> uint
}
fn foo(v: &V) { /* In theory, V::len() would give the 
length */ }


Problem is, you can't write static functions that do not reference 
`Self` today [1].


In any case what you *really* want is something like

trait VectorN {
const len: uint;
}
fn foo(v: &V) { /* Here, V::len is a constant */ }

which certainly doesn't work today.

There is some design work needed here.  In general, this seems to be 
related to the desire for associated types [2].  We need to spend some 
time thinking about what we want to support.  I imagine we'll wind up 
postponing some or all such features to after Rust 1.0.


I guess the closest thing that does work today is something like:

trait VectorN {
fn len(&self) -> uint;
}
fn foo(v: &V) { /* v.len() gives the length */

This has the downside that it requires an instance of `V` to be used.


Niko

[1] I thought there was an issue on this, but I couldn't find it.
[2] https://github.com/mozilla/rust/issues/5033
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Many little questions while writing a Vector class

2013-02-21 Thread Patrick Walton

On 2/21/13 8:33 AM, Ashish Myles wrote:

O wow, I don't know how I missed that.  Coming from other languages,
though "join" seem to be the common name for this. Even the following
search does not bring up any reference to connect.
http://www.google.com/search?q=site%3Astatic.rust-lang.org%2Fdoc%2F+join
Perhaps a note could be made in the docs indicating that vec::connect()
acts like a vector join with a string separator in various other languages?


We should probably just rename it to `join`. The reason why it's called 
`connect` is that in ancient versions of Rust `join` was a keyword (to 
join tasks).


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


Re: [rust-dev] Many little questions while writing a Vector class

2013-02-21 Thread Ashish Myles
Thanks for all the answers.

On Thu, Feb 21, 2013 at 9:17 AM, Niko Matsakis  wrote:

>
>
> Ashish Myles wrote:
>
>> Lots of questions.
>>
>> 1. Is there an array string join function?  I looked through possible
>> pertinent vector- and string-related modules and I didn't see
>> something equivalent.
>>
> vec::connect() will join a vector of strings into one string.
>
>
O wow, I don't know how I missed that.  Coming from other languages, though
"join" seem to be the common name for this. Even the following search does
not bring up any reference to connect.
http://www.google.com/search?q=site%3Astatic.rust-lang.org%2Fdoc%2F+join
Perhaps a note could be made in the docs indicating that vec::connect()
acts like a vector join with a string separator in various other languages?


>  2. Any particular reason to_str() for arrays (defined in in std::to_str)
>>is defined only for unique arrays? i.e.
>> impl ~[A]: ToStr {
>> // ...
>> }
>>rather than for all array types via &?
>> impl &[A]: ToStr {
>> // ...
>> }
>>Modifying the definition seems to allow it to work for managed and
>> static
>>arrays.
>>
> I don't think there's a good reason for this.
>
>  3. What is the rust idiom for defining a constant value associated with a
>>class?
>>
> Declare a constant in the same module as the struct.  Whereas C++ uses the
> class/struct as the primary organizing unit for code, Rust tends to use
> modules to group together related functions, types, constants, and so
> forth.  Similarly, the Rust translation for a C++ class is a module
> containing a struct, impl, etc.
>
>
C++ has both class- and namespace-level constants as they have different
uses. In the example, I have a class/struct-level constant. For example
struct Vector2 {
enum { N = 2 };
T m_v[N];
};
struct Vector3 {
enum { N = 3 };
T m_v[N];
};
Imagine also, as in my macro question below -- a vector struct is created
based on some integer dimension value. So that dimension constant should
logically be defined in the struct in that case as well.
So, I am to presume from your answer that there is no way to create
class-associated constants?  Is this worth considering adding to Rust?


>  6. Is there any way to get a number into a macro and splice it into a
>> class
>>name? i.e. Something like the intention behind the following.
>> macro_rules! VectorT {
>> // invoke it like VectorT
>> ($name:ident, $n:expr) => (
>> struct Vector$n {
>> priv m_v: [mut T * $n];
>> }
>> );
>> }
>>
> I don't know the answer to this.
>
>
I look forward to anyone else taking a stab at how one could accomplish
something similar in Rust. One obvious but not very DRY way would be to
send in all pre-concatenated identifiers. Like in this case, one could
re-write the macro to be invoked as VectorT(Vector3, 3).  If the macro
creates multiple identifiers (including some associate with helper
classes/functions) based on just concatenating the numeric value, then the
invocation could get pretty ugly and would leak too much about the
underlying implementation.

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


Re: [rust-dev] Many little questions while writing a Vector class

2013-02-21 Thread Jack Moffitt
> FWIW Qt uses `count()`. (but also has size() for STL compatibility,
> and length() as well when it makes sense...)

Clojure uses count as well. I'd prefer size or count, but I suppose
another question is whether verbs or adjectives are preferred for this
kind of thing. That should probably be consistent in the standard lib
as well.

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


Re: [rust-dev] Many little questions while writing a Vector class

2013-02-21 Thread Gábor Lehel
On Thu, Feb 21, 2013 at 3:17 PM, Niko Matsakis  wrote:
>
>
> Ashish Myles wrote:
>> 5. Consistency of len/size:
>>Each language seems to have its own standard for specifying container
>>size. I thought Rust's convention was len from vector, dvec, list, etc,
>>but deque uses size.  Should that also be len?  Or rather, as "size" is
>>the more generic term (applies semantically to arbitrary containers
>> like
>>trees and maps), should "size" be the standard? Or, like ruby, perhaps
>>both could be allowed.
>
> Good question.  This is the sort of thing that we are going to be addressing
> as we cleanup the libraries.  I agree we should settle on one.  I don't
> personally care which it is. I'm personally not bothered by the semantic
> mismatch of a set having a length, but I guess `size()` would be the most
> broadly applicable and least likely to inspire later flame wars.

FWIW Qt uses `count()`. (but also has size() for STL compatibility,
and length() as well when it makes sense...)


-- 
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] Many little questions while writing a Vector class

2013-02-21 Thread Niko Matsakis



Ashish Myles wrote:

Lots of questions.

1. Is there an array string join function?  I looked through possible
pertinent vector- and string-related modules and I didn't see
something equivalent.

vec::connect() will join a vector of strings into one string.

2. Any particular reason to_str() for arrays (defined in in std::to_str)
   is defined only for unique arrays? i.e.
impl ~[A]: ToStr {
// ...
}
   rather than for all array types via &?
impl &[A]: ToStr {
// ...
}
   Modifying the definition seems to allow it to work for managed and 
static

   arrays.

I don't think there's a good reason for this.

3. What is the rust idiom for defining a constant value associated with a
   class?
Declare a constant in the same module as the struct.  Whereas C++ uses 
the class/struct as the primary organizing unit for code, Rust tends to 
use modules to group together related functions, types, constants, and 
so forth.  Similarly, the Rust translation for a C++ class is a module 
containing a struct, impl, etc.
4. How do I copy between mutable/immutable types and from dynamic to 
static

   array types?
let a : ~[int] = ~[1,2,3];
// I know these are by design, but I don't know how to get the desired
// effect.
let b : [int * 3] = copy a; // fails due to storage mismatch
Hmm, I don't know of a convenient way to do this.  Obviously it would 
fail if the length of `a` were incorrect.  You probably have to do 
something like the following:


let mut b: [int*3] = [0, ..3]; // initialize with zeroes
assert a.len() == 3;
for uint::range(0, 3) |i| { b[i] = a[i]; }

I imagine there is a "memcpy" like function for vectors that you could 
use to avoid the loop, but I don't know it's name off the top of my head.

let c : ~[mut int] = copy a; // fails due to mutability mismatch
You should not be using a type like ~[mut int].   That is deprecated.  
Mutability is inherited through ~ pointers (indeed through any kind of 
ownership), so you can write:


let mut c = a; // moves a by default, use `copy a` if you want to 
use `a` later

c[0] += 1; // and so on...

5. Consistency of len/size:
   Each language seems to have its own standard for specifying container
   size. I thought Rust's convention was len from vector, dvec, list, etc,
   but deque uses size.  Should that also be len?  Or rather, as "size" is
   the more generic term (applies semantically to arbitrary containers 
like

   trees and maps), should "size" be the standard? Or, like ruby, perhaps
   both could be allowed.
Good question.  This is the sort of thing that we are going to be 
addressing as we cleanup the libraries.  I agree we should settle on 
one.  I don't personally care which it is. I'm personally not bothered 
by the semantic mismatch of a set having a length, but I guess `size()` 
would be the most broadly applicable and least likely to inspire later 
flame wars.
6. Is there any way to get a number into a macro and splice it into a 
class

   name? i.e. Something like the intention behind the following.
macro_rules! VectorT {
// invoke it like VectorT
($name:ident, $n:expr) => (
struct Vector$n {
priv m_v: [mut T * $n];
}
);
}

I don't know the answer to this.


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


[rust-dev] Many little questions while writing a Vector class

2013-02-20 Thread Ashish Myles
Lots of questions.

1. Is there an array string join function?  I looked through possible
pertinent vector- and string-related modules and I didn't see
something equivalent.


2. Any particular reason to_str() for arrays (defined in in std::to_str)
   is defined only for unique arrays? i.e.
impl ~[A]: ToStr {
// ...
}
   rather than for all array types via &?
impl &[A]: ToStr {
// ...
}
   Modifying the definition seems to allow it to work for managed and static
   arrays.


3. What is the rust idiom for defining a constant value associated with a
   class? As an example, I defined N below for the vector class in C++ and
   immediately used it to define data members.
struct Vector3 {
enum { N = 3 };
T m_v[N];
};

   In static contexts like above, especially when there may be multiple data
   members dependent on the constant, I just wanted to associate a name with
   them. I am already defining a len() method as below to return this value.
struct Vector3 {
priv m_v: [mut T * 3]
}

impl Vector3 {
fn len(&self) -> uint { 3u; }
}
Rust does not seem to allow adding const definitions inside the struct.


4. How do I copy between mutable/immutable types and from dynamic to static
   array types?
let a : ~[int] = ~[1,2,3];
// I know these are by design, but I don't know how to get the desired
// effect.
let b : [int * 3] = copy a; // fails due to storage mismatch
let c : ~[mut int] = copy a; // fails due to mutability mismatch


5. Consistency of len/size:
   Each language seems to have its own standard for specifying container
   size. I thought Rust's convention was len from vector, dvec, list, etc,
   but deque uses size.  Should that also be len?  Or rather, as "size" is
   the more generic term (applies semantically to arbitrary containers like
   trees and maps), should "size" be the standard? Or, like ruby, perhaps
   both could be allowed.


6. Is there any way to get a number into a macro and splice it into a class
   name? i.e. Something like the intention behind the following.
macro_rules! VectorT {
// invoke it like VectorT
($name:ident, $n:expr) => (
struct Vector$n {
priv m_v: [mut T * $n];
}
);
}
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev