Re: [rust-dev] Many little questions while writing a Vector class
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
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
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
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
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
> 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
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
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
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