Re: [rust-dev] Porting some nesC features to rust?
And just in case there is a confusion (as I have noticed others to have), it might help to see a specific example comparing static dispatch with dynamic. // This is a single function for all types implementing the LCD Trait. fn foo(x : LCD) { // x's type is LCD rather than the actual type of the object being passed in x.line(); // dynamic dispatch } // Like C++ templates, this generates a function for each type T that implements LCD. fn fooT : LCD(x : T) { // x's type is T rather than LCD x.line(); // static dispatch based on type T known at compile-time } On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay danielmi...@gmail.com wrote: On 02/04/14 06:25 AM, Vladimir Pouzanov wrote: If I get it right, calls to traits are resolved in runtime (so, traits are kind of similar to C++ virtual methods). All method calls on regular types are resolved via static dispatch, whether or not they come from a trait. For example, consider a generic function like the following: fn minT: TotalOrd(a: T, b: T) - T { if a b { a } else { b } } This function performs a *static* call of the `lt` method defined on the `Ord` trait that `TotalOrd` inherits from. Generics are fully expanded at compile-time just as C++ templates are. Rust also allows using traits as boxed objects, but this is an entirely transparent choice. They're almost always used for static dispatch via trait bounds on generics, or simply outside of generics. What I'm proposing here is a compile-time approach. Let's say we have the following trait: pub trait LCD { fn line(mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: u8); fn rect(mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8); fn fillrect(mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32, color: u8); fn putc(mut self, value: char); fn puts(mut self, s: str); fn flush(self); fn clear(mut self); } which defined a LED screen. There are two structs implementing it: C12832 and ILI9341 (two different lcd controllers). So I want my app to print hello world on lcd, I write the following code: let mut lcd = lcd_c12832::C12832::new(spi); let mut l: mut lcd::LCD = lcd as mut lcd::LCD; l.puts(hello, world); Which results in a runtime dispatch, a slower and bigger code than the one I'd have without a trait. You can call methods defined on a trait without boxing the object as a trait object. The ability to perform dynamic dispatch via a trait object is totally optional. The methods can also be called directly, including inside a generic function by specifying the trait as a type parameter bound. You can simply call the `puts` method directly on the `lcd` object without a cast. A second problem is there is no easy way to write unified code that supports both the lcds based on passed in --cfg, as I can't apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of problematic to return a LCD out from it given that there is no heap and no analog of placement new from C++. Rust supports generic functions, and you can write code supporting both types by making it generic. The choice between static dispatch and dynamic dispatch is entirely up to you in the current system. Proposed binding concept solves those two problems: #[cfg(lcd_c12832)] let Binding: binding { let lcd: lcd_c12832::C12832; let main: Main; bind main.lcd = lcd; } at this point of time compiler can be sure about what struct is implementing LCD trait for main.lcd and can bind the function bodies as compile time, inlining them if applicable. This also might be something that is already implemented, please advice. The goal here is to minimise runtime code being executed and its size. ___ 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] Possible bug? os::args() then split then print
On Tue, Feb 25, 2014 at 11:00 AM, Phil Dawes rustp...@phildawes.net wrote: fn main() { let arr : ~[str] = std::os::args()[1].split_str(::).collect(); std::io::println(first + arr[0]); std::io::println(first again + arr[0]); } I am working on an older version of the compiler that fails to compile this code, giving an error about the reference to the return value of std::os::args() not being valid for the duration of its use. Does let args = std::os::args(); let arr : ~[str] = args[1].split_str(::).collect(); work properly? Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How to use dynamic polymorphism with collection
On Sat, Feb 8, 2014 at 6:48 PM, Ashish Myles marci...@gmail.com wrote: On Sat, Feb 8, 2014 at 1:21 PM, Philippe Delrieu philippe.delr...@free.fr wrote: pub trait Base { fn do_base(self); } struct TestBase; impl Base for TestBase{ fn do_base(self){ println!(ici); } } trait GenerciFn{ fn do_genericT: Base(self, base: T); } struct DoGenericFn; impl GenerciFn for DoGenericFn { fn do_genericT: Base(self, base: T){ base.do_base(); } } struct ToTestStr{ vec_gen: ~[~TestBase], } impl ToTestStr{ fn testgencallT: GenerciFn(self, gen: T){ for base in self.vec_gen.iter(){ //let test = base as ~TestBase; gen.do_generic(**base); } } } #[main] fn main() { let base = TestBase; let test = ToTestStr {vec_gen: ~[~base],}; let gen = DoGenericFn; test.testgencall(gen); It took me a few attempts to get the for loop right, but here you go. pub trait Base { fn do_base(self); } struct TestBase; impl Base for TestBase { fn do_base(self) { println!(ici); } } trait GenericFn { fn do_generic(self, base: Base); } struct DoGenericFn; impl GenericFn for DoGenericFn { fn do_generic(self, base: Base) { base.do_base(); } } struct ToTestStr { vec_gen: ~[~Base], } impl ToTestStr { fn testgencallT: GenericFn(self, gen: T){ for ref base in self.vec_gen.iter() { gen.do_generic(**base); } } } #[main] fn main() { let testbase = TestBase; let test = ToTestStr {vec_gen: ~[~testbase as ~Base],}; let gen = DoGenericFn; test.testgencall(gen); } Also, for a little more runtime polymorphism, you could change testgencall's declaration to fn testgencall(self, gen: GenericFn) { ... } ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Converting ~[T] embedded in struct to [T]
Thanks for the detailed explanations! On Sun, Jan 19, 2014 at 2:01 AM, Alex Crichton a...@crichton.co wrote: fn borrow1'a('a self) - 'a int { match (self) { // error: mismatched types: expected `'a int` but found `~int` // (expected -ptr but found ~-ptr) Foo(ref v) = *v } } This doesn't work because the local variable v has type ~int, when you dereference this you get something of type ~int which if you load is a move so you're not allowed to do that. Additionally, the return type wants int when you're giving it ~int What's the reason ~T not coerced to T the same way as in the main() function and borrow3 -- ie. why isn't it automatically converted to **v as it is in these cases? The conversion is identical, no? The inability in this particular context seems rather arbitrary. ... *snip* ... fn borrow3'a('a self) - 'a [int] { match (self) { // error: mismatched types: expected `'a [int]` but found // `V2` (expected vector but found -ptr) FooVec(ref v) = do_borrow(*v) } } } This doesn't work because the do_borrow function takes something of type int, not ~[int] (which is the type of *v). You'd need to rewrite the borrow function to take [int] instead of int. Another solution for vectors is to return v.as_slice() which is a function that will convert all forms of vectors to its slice representation ([T]) Hope that helps! Wow, thanks...this worked (surprisingly to me). fn do_borrow_ary'a, T(t : 'a [T]) - 'a [T] { t } ... fn borrow3'a('a self) - 'a [int] { match (self) { // WORKS FooVec(ref v) = do_borrow_ary(*v) } } This leads to multiple points of confusion for me. It seems that [T] is special-cased in a way that prevents it from being used as a regular type. In particular, 1. How did do_borrow_ary manage to coerce ~[T] to [T] when the other methods (eg. automatic insertion of *) failed? Is this special-cased by the compiler? Is there some way to trigger this coercion without requiring an intermediate function like do_borrow_ary (say, if one wants to return a static array value type, not a slice)? 2. Why did fn do_borrow'a, T(t : 'a T) - 'a T fail to match types? Isn't [S] a type T and of the same kind? (Any other language also exhibit this dichotomy?) This prevents one from being able to write a truly generic function -- one must duplicate the code for T and [T] variations. Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Cloning a statically-sized array
Thanks! I was half thinking of implementing this. :) On Sun, Jan 19, 2014 at 1:04 AM, Jason Fager jfa...@gmail.com wrote: The workaround for this is a wrapper struct around the fixed-size vec, with the trait methods you want impl'd on the wrapper. I've got a macro for this: https://github.com/jfager/d3cap/blob/master/fixed_vec_macros.rs So to wrap a [u16,..8], you'd say something like: fixed_vec!(WrapperType, u16, 8) and get a back a type called WrapperType implementing IterBytes, Eq, Ord, and Clone (would be easy to add others). Not ideal, but useful until this gets straightened out. On Sun, Jan 19, 2014 at 12:19 AM, Daniel Micay danielmi...@gmail.comwrote: On Sun, Jan 19, 2014 at 12:17 AM, Ashish Myles marci...@gmail.com wrote: Now, I already know that statically-sized arrays of primitives are implicitly copyable, but consider, for example, a statically-sized array of a non-copyable but Clone-able type. I find that for v of type [T, ..2], v.clone() is not a static array. Perhaps it's because v is being implicitly treated as [T] instead. Eg. -- fn make_cloneT : Clone(a : T) - T { a.clone(); } fn main() { let a : [int, ..2] = [1, 2]; // error: failed to find an implementation of trait std::clone::Clone // for [int, .. 2] make_clone(a); let a : [int, ..2] = [1, 2]; // error: mismatched types: expected `[int, .. 2]` but found `[int]` // ([] storage differs: expected 2 but found ) let b : [int, ..2] = a.clone(); } -- So is it a missing feature of rust that Clone is not supported generated for statically-sized arrays or is there a more fundamental reason that it doesn't exist? Ashish Clone is entirely a library feature, and Rust currently provides no way to implement methods on fixed-size arrays. The latter is the real issue, because there are other methods like `Eq` that should be implemented on them too. ___ 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] Converting ~[T] embedded in struct to [T]
Thanks! I appreciate the detailed answers and look forward to future changes. :) And I had already run into and started reading Niko's article you linked for DSTs. I love the thorough analyses you guys go through for each feature. Ashish On Sun, Jan 19, 2014 at 1:17 PM, Alex Crichton a...@crichton.co wrote: What's the reason ~T not coerced to T the same way as in the main() function and borrow3 -- ie. why isn't it automatically converted to **v as it is in these cases? The conversion is identical, no? The inability in this particular context seems rather arbitrary. Sadly this is correct. Right now type coercion does not happen in all places, where the return expression is one of them. Coercion is allowed in let expressions through type ascription and around method calls. The conversion is indeed similar, and we've talked about refining this sort of behavior in the past. This is partly the topic of https://github.com/mozilla/rust/issues/10504, but specifically concerning return type coercion I don't think a bug exists. It can be argued though that coercion on the return type is a little different than coercion on a function call, though. You've explicitly listed the return type as int, but then you return something of type ~int. This reasoning isn't very strong though, and I think I would personally like to see coercion *everywhere* as opposed to just a few locations. Wow, thanks...this worked (surprisingly to me). fn do_borrow_ary'a, T(t : 'a [T]) - 'a [T] { t } ... fn borrow3'a('a self) - 'a [int] { match (self) { // WORKS FooVec(ref v) = do_borrow_ary(*v) } } This leads to multiple points of confusion for me. It seems that [T] is special-cased in a way that prevents it from being used as a regular type. In particular, That is correct. Sadly you cannot instantiate a type parameter T with something that looks like [U] (but soon you will be able to)! This is the source of a number of difficulties throughout the stdlib and language, which is why we definitely intend to fix it! 1. How did do_borrow_ary manage to coerce ~[T] to [T] when the other methods (eg. automatic insertion of *) failed? Is this special-cased by the compiler? Is there some way to trigger this coercion without requiring an intermediate function like do_borrow_ary (say, if one wants to return a static array value type, not a slice)? This sort of coercion is special-cased in the compiler to allow it to be possible. 2. Why did fn do_borrow'a, T(t : 'a T) - 'a T fail to match types? Isn't [S] a type T and of the same kind? (Any other language also exhibit this dichotomy?) This prevents one from being able to write a truly generic function -- one must duplicate the code for T and [T] variations. Ah, it appears I answered this above! I would recommend reading http://smallcultfollowing.com/babysteps/blog/2014/01/05/dst-take-5/, the most recent development in DST and it should explain how we intend to allow this in the future. Soon, hopefully! ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Converting ~[T] embedded in struct to [T]
I understand as per a previous discussion that the owned box ~[T] doesn't quite have the semantics of a unique *pointer*. Below include my successes in some borrowing scenarios and analogous failed attempts at borrowing a reference to a unique pointer to an array within a FooVec struct. How do I do this? Is there a borrow() type function/method provided for owned boxes somewhere? (I see some borrow() stuff within the libstd source, but doesn't seem to be relevant.) -- fn main() { let a : ~[int] = ~[1,2,3]; // WORKS (borrow1 style below) let b : [int] = a; } fn do_borrow'a, T(t : 'a T) - 'a T { t } struct Foo(~int); impl Foo { fn borrow1'a('a self) - 'a int { match (self) { // error: mismatched types: expected `'a int` but found `~int` // (expected -ptr but found ~-ptr) Foo(ref v) = *v } } fn borrow2'a('a self) - 'a int { match (self) { // WORKS Foo(ref v) = **v } } fn borrow3'a('a self) - 'a int { match (self) { // WORKS Foo(ref v) = do_borrow(*v) } } } struct FooVec(~[int]); impl FooVec { fn borrow1'a('a self) - 'a [int] { match (self) { // error: mismatched types: expected `'a [int]` but found // `~[int]` ([] storage differs: expected 'a but found ~) FooVec(ref v) = *v } } fn borrow2'a('a self) - 'a [int] { match (self) { // error: type ~[int] cannot be dereferenced FooVec(ref v) = **v } } fn borrow3'a('a self) - 'a [int] { match (self) { // error: mismatched types: expected `'a [int]` but found // `V2` (expected vector but found -ptr) FooVec(ref v) = do_borrow(*v) } } } -- ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Cloning a statically-sized array
Now, I already know that statically-sized arrays of primitives are implicitly copyable, but consider, for example, a statically-sized array of a non-copyable but Clone-able type. I find that for v of type [T, ..2], v.clone() is not a static array. Perhaps it's because v is being implicitly treated as [T] instead. Eg. -- fn make_cloneT : Clone(a : T) - T { a.clone(); } fn main() { let a : [int, ..2] = [1, 2]; // error: failed to find an implementation of trait std::clone::Clone // for [int, .. 2] make_clone(a); let a : [int, ..2] = [1, 2]; // error: mismatched types: expected `[int, .. 2]` but found `[int]` // ([] storage differs: expected 2 but found ) let b : [int, ..2] = a.clone(); } -- So is it a missing feature of rust that Clone is not supported generated for statically-sized arrays or is there a more fundamental reason that it doesn't exist? Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Macros expanding to multiple statements
Rust 0.9 indicates that support for expansion of macros into multiple statements is now supported, and the following example from the test suite works for me. https://github.com/mozilla/rust/blob/master/src/test/run-pass/macro-multiple-items.rs However, I receive an error for the following code #[feature(macro_rules)]; macro_rules! my_print( ($a:expr, $b:expr) = ( println!({:?}, a); println!({:?}, b); ); ) fn main() { let a = 1; let b = 2; my_print!(a, b); } (Note that the ^~~ below points at println.) $ rustc macro_ignores_second_line.rs macro_ignores_second_line.rs:6:9: 6:16 error: macro expansion ignores token `println` and any following macro_ignores_second_line.rs:6 println!({:?}, b); ^~~ error: aborting due to previous error task 'rustc' failed at 'explicit failure', /home/marcianx/devel/rust/checkout/rust/src/libsyntax/diagnostic.rs:75 task 'main' failed at 'explicit failure', /home/marcianx/devel/rust/checkout/rust/src/librustc/lib.rs:453 What's the right way to do this? Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Macros expanding to multiple statements
Ah, I didn't realize the distinction. I am comparing the code in the first comment in the bug you linked against the test suite example I linked. I guess the distinction between items and statements is that items correspond to code outside any method, whereas statements are defined as code within a method, and macro expansions in the latter case seem to be broken even in the case of a single statement. Please correct me if I am wrong. Ashish On Sat, Jan 11, 2014 at 9:43 PM, Huon Wilson dbau...@gmail.com wrote: That test is for multiple *items*, not statements. For the moment, you just have to wrap the interior of a macro expanding to an expression in a set of braces, so that it becomes a single statement. macro_rules! my_print( ($a:expr, $b:expr) = ( { println!({:?}, a); println!({:?}, b); } ); ) Multi-statement macros are covered by https://github.com/mozilla/rust/issues/10681 . Huon On 12/01/14 13:40, Ashish Myles wrote: Rust 0.9 indicates that support for expansion of macros into multiple statements is now supported, and the following example from the test suite works for me. https://github.com/mozilla/rust/blob/master/src/test/run-pass/macro-multiple-items.rs However, I receive an error for the following code #[feature(macro_rules)]; macro_rules! my_print( ($a:expr, $b:expr) = ( println!({:?}, a); println!({:?}, b); ); ) fn main() { let a = 1; let b = 2; my_print!(a, b); } (Note that the ^~~ below points at println.) $ rustc macro_ignores_second_line.rs macro_ignores_second_line.rs:6:9: 6:16 error: macro expansion ignores token `println` and any following macro_ignores_second_line.rs:6 println!({:?}, b); ^~~ error: aborting due to previous error task 'rustc' failed at 'explicit failure', /home/marcianx/devel/rust/checkout/rust/src/libsyntax/diagnostic.rs:75 task 'main' failed at 'explicit failure', /home/marcianx/devel/rust/checkout/rust/src/librustc/lib.rs:453 What's the right way to do this? Ashish ___ Rust-dev mailing listRust-dev@mozilla.orghttps://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
[rust-dev] What type to put for index when impl-ing Index?
The following implementation of Index for Foo works fine. struct Foo([f64, ..3]); impl Indexuint, f64 for Foo { fn index(self, index: uint) - f64 { match self { Foo(ref v) = v[*index].clone() } } } fn main() { let tmp : uint = 0; let foo = Foo([1.0, 2.0, 3.0]); println!({:?}, foo[tmp]); } But if tmp is of type int, then I get an int-uint type mismatch failure. So I tried the following. use std::num::Int; ... implIdx : Int IndexIdx, f64 for Foo { fn index(self, index: Idx) - f64 { match self { Foo(ref v) = v[*index].clone() } } } But I get error: mismatched types: expected integral type but found `Idx` with the error pointing at *index above. What's the right way to go about implementing generic operator indexing? Or does one always require conversion to uint (in the first case above) on the caller's side? Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] What type to put for index when impl-ing Index?
That'll do it, thanks! :) Here's to hoping that the compiler is smart enough to remove the bounds-checks and the None pathway for when I is one of the unsigned integer primitives. Ashish On Wed, Jan 8, 2014 at 11:21 PM, Brendan Zabarauskas bjz...@yahoo.com.auwrote: struct Foo([f64, ..3]); implI: Int IndexI, f64 for Foo { fn index(self, index: I) - f64 { let index = index.to_uint().unwrap(); match self { Foo(ref v) = v[index].clone() } } } fn main() { let tmp : uint = 0; let foo = Foo([1.0, 2.0, 3.0]); println!({:?}, foo[tmp]); } On 9 Jan 2014, at 2:08 pm, Ashish Myles marci...@gmail.com wrote: The following implementation of Index for Foo works fine. struct Foo([f64, ..3]); impl Indexuint, f64 for Foo { fn index(self, index: uint) - f64 { match self { Foo(ref v) = v[*index].clone() } } } fn main() { let tmp : uint = 0; let foo = Foo([1.0, 2.0, 3.0]); println!({:?}, foo[tmp]); } But if tmp is of type int, then I get an int-uint type mismatch failure. So I tried the following. use std::num::Int; ... implIdx : Int IndexIdx, f64 for Foo { fn index(self, index: Idx) - f64 { match self { Foo(ref v) = v[*index].clone() } } } But I get error: mismatched types: expected integral type but found `Idx` with the error pointing at *index above. What's the right way to go about implementing generic operator indexing? Or does one always require conversion to uint (in the first case above) on the caller's side? Ashish ___ 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] Auto-borrow/deref (again, sorry)
I think I see the confusion (as I suffered from the same point of confusion). So let me restate your answer and please correct me of I am wrong. 1. mut int and mut int are different types and the former doesn't automatically convert to the latter. 2. The way to get the latter from the former is to say mut i since i is defined as taking a non-mut borrow even if i is mut. (This was the point of confusion I believe.) 3. No explicit conversion is needed within foo() since the type of i is already mut int. Ashish On Dec 28, 2013 1:33 PM, Kevin Ballard ke...@sb.org wrote: We have to say `mut i` in main() because `i` is non-mutable. We’re explicitly taking a mutable borrow. But once it’s in foo(), it’s *already* mutable. The type `mut int` carries its mutability with it. Having to say `mut` again makes no sense and is nothing but pure noise. -Kevin On Dec 27, 2013, at 4:59 PM, Vadim vadi...@gmail.com wrote: For the same reason we currently have to say `mut i` in main() - to explicitly acknowledge that the callee may mutate i. By the same logic, this should be done everywhere. On Wed, Dec 25, 2013 at 3:11 PM, Kevin Ballard ke...@sb.org wrote: On Dec 25, 2013, at 5:17 PM, Vadim vadi...@gmail.com wrote: I agree that unexpected mutation is undesirable, but: - requiring 'mut' is orthogonal to requiring '' sigil, IMHO, - as currently implemented, Rust does not always require mut when callee mutates the argument, for example: fn main() { let mut i: int = 0; foo(mut i); println!({}, i); } fn foo(i: mut int) { bar(i); // no mut! } fn bar(i: mut int) { *i = *i + 1; } Note that invocation of bar() inside foo() does not forewarn reader by requiring 'mut'. Wouldn't you rather see this?: fn main() { let mut i: int = 0; foo(mut i); println!({}, i); } fn foo(i: mut int) { bar(mut i); } fn bar(i: mut int) { i = i + 1; } What is the point of adding `mut` here? bar() does not need `mut` because calling bar(i) does not auto-borrow i. It’s *already* a `mut int`. -Kevin ___ 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] Define copyable types for [T, ..2] static vector initialization
Previously we had the Copy trait, which when implemented by trait T allowed one to write [Zero::zero(), ..SZ] where T implemented the Zero trait. But now I am not sure how to get that behavior. Concretely, here is the code I want to get compiling. (Just to check, I added both Clone and DeepClone, even though they don't automatically allow implicit copyability). use std::num::Zero; enum Constants { SZ = 2 } struct FooT([T, ..SZ]); implT : Clone + DeepClone + Zero FooT { pub fn new() - FooT { Foo([Zero::zero(), ..SZ]) } } The error I get is: error: copying a value of non-copyable type `T` tmp.rs:155 Foo([Zero::zero(), ..SZ]) Any way to do this? Or is this no longer supported for general types? Any intentions to add this behavior again? Otherwise, I can't even initialize my struct while being agnostic to the specific value of SZ. Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Define copyable types for [T, ..2] static vector initialization
Is there a plan to support fix-sized vector initialization without manual replication? My example is just a simplified version -- this was part of a macro that takes the size as input ($n:expr) and the initialization was [Zero::zero(), .. $n]. Is this use case no longer intended to be supported? On Nov 29, 2013 6:47 PM, Huon Wilson dbau...@gmail.com wrote: On 30/11/13 10:33, Ashish Myles wrote: Previously we had the Copy trait, which when implemented by trait T allowed one to write [Zero::zero(), ..SZ] where T implemented the Zero trait. But now I am not sure how to get that behavior. Concretely, here is the code I want to get compiling. (Just to check, I added both Clone and DeepClone, even though they don't automatically allow implicit copyability). use std::num::Zero; enum Constants { SZ = 2 } struct FooT([T, ..SZ]); implT : Clone + DeepClone + Zero FooT { pub fn new() - FooT { Foo([Zero::zero(), ..SZ]) } } The error I get is: error: copying a value of non-copyable type `T` tmp.rs:155 Foo([Zero::zero(), ..SZ]) Any way to do this? Or is this no longer supported for general types? Any intentions to add this behavior again? Otherwise, I can't even initialize my struct while being agnostic to the specific value of SZ. Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev Initialising a fixed size vector [T, ..n] by [foo(), .. n] unfortunately requires that `T` is implicitly copyable (that is, it doesn't move ownership when passed by value), and there's no way around this other than [foo(), foo(), foo(),...]. Huon ___ 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] Define copyable types for [T, ..2] static vector initialization
That's some seriously nifty stuff, which got my stuff compiling again. :) But for the long term, it would be nice to have a syntax that behaves as was the case with the Copy trait -- it takes a single value and clones it into the elements of the static array. Or perhaps the developers disagree and consider it to be a niche use (static arrays with sizes known a-priori when writing the code) -- it would be good to get some clarity on this. Thanks, Ashish On Fri, Nov 29, 2013 at 10:20 PM, Kevin Ballard ke...@sb.org wrote: If you're willing to use unsafe code and std::unstable, you can do it. use std::num::Zero; use std::unstable::intrinsics; enum Constants { SZ = 2 } struct FooT([T, ..SZ]); implT: Clone + DeepClone + Zero FooT { pub fn new() - FooT { let mut ary: [T, ..SZ]; unsafe { ary = intrinsics::uninit(); for i in range(0u, SZ as uint) { intrinsics::move_val_init(mut ary[i], Zero::zero()); } } Foo(ary) } } -Kevin On Nov 29, 2013, at 7:05 PM, Ashish Myles marci...@gmail.com wrote: Is there a plan to support fix-sized vector initialization without manual replication? My example is just a simplified version -- this was part of a macro that takes the size as input ($n:expr) and the initialization was [Zero::zero(), .. $n]. Is this use case no longer intended to be supported? On Nov 29, 2013 6:47 PM, Huon Wilson dbau...@gmail.com wrote: On 30/11/13 10:33, Ashish Myles wrote: Previously we had the Copy trait, which when implemented by trait T allowed one to write [Zero::zero(), ..SZ] where T implemented the Zero trait. But now I am not sure how to get that behavior. Concretely, here is the code I want to get compiling. (Just to check, I added both Clone and DeepClone, even though they don't automatically allow implicit copyability). use std::num::Zero; enum Constants { SZ = 2 } struct FooT([T, ..SZ]); implT : Clone + DeepClone + Zero FooT { pub fn new() - FooT { Foo([Zero::zero(), ..SZ]) } } The error I get is: error: copying a value of non-copyable type `T` tmp.rs:155 Foo([Zero::zero(), ..SZ]) Any way to do this? Or is this no longer supported for general types? Any intentions to add this behavior again? Otherwise, I can't even initialize my struct while being agnostic to the specific value of SZ. Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev Initialising a fixed size vector [T, ..n] by [foo(), .. n] unfortunately requires that `T` is implicitly copyable (that is, it doesn't move ownership when passed by value), and there's no way around this other than [foo(), foo(), foo(),...]. Huon ___ 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] Define copyable types for [T, ..2] static vector initialization
+1 on specifying function. That potentially lowers the requirements on the Traits -- e.g. don't have to force clone-ability as long as you can create+move it; perhaps even create it in place. I have been waiting on integer parameters on traits since I first ran into Rust, but the rust team might be avoiding that to prevent getting Turing complete generics/templates. Ashish On Sat, Nov 30, 2013 at 12:39 AM, Kevin Ballard ke...@sb.org wrote: Personally, I think it would be nicer to just have a syntax that says create an array of length N by executing the following expression (typically a function call) N times. Something along the lines of let ary = [Foo::new().., ..32]; This would be more generic, because it will work with non-Clonable values, and if you wanted cloned values you'd just say let ary = [foo.clone().., ..32]; Although if we ever get the ability to make generics that have integral parameters (which is necessary to implement traits on arbitrary arrays) then we could do this in the libraries by writing a function like I had before. Something like the following: libstd/array.rs: #[inline] fn from_fnT, N as uint init(f: |uint| - T) - [T, ..N] { let mut ary: [T, ..N]; unsafe { ary = intrinsics::uninit(); for i in range(0u, N) { intrinsics::move_val_init(mut ary[i], f(i)); } } ary } This would let you call it like Foo(array::from_fn(|_| Zero::zero())). -Kevin On Nov 29, 2013, at 8:37 PM, Ashish Myles marci...@gmail.com wrote: That's some seriously nifty stuff, which got my stuff compiling again. :) But for the long term, it would be nice to have a syntax that behaves as was the case with the Copy trait -- it takes a single value and clones it into the elements of the static array. Or perhaps the developers disagree and consider it to be a niche use (static arrays with sizes known a-priori when writing the code) -- it would be good to get some clarity on this. Thanks, Ashish On Fri, Nov 29, 2013 at 10:20 PM, Kevin Ballard ke...@sb.org wrote: If you're willing to use unsafe code and std::unstable, you can do it. use std::num::Zero; use std::unstable::intrinsics; enum Constants { SZ = 2 } struct FooT([T, ..SZ]); implT: Clone + DeepClone + Zero FooT { pub fn new() - FooT { let mut ary: [T, ..SZ]; unsafe { ary = intrinsics::uninit(); for i in range(0u, SZ as uint) { intrinsics::move_val_init(mut ary[i], Zero::zero()); } } Foo(ary) } } -Kevin On Nov 29, 2013, at 7:05 PM, Ashish Myles marci...@gmail.com wrote: Is there a plan to support fix-sized vector initialization without manual replication? My example is just a simplified version -- this was part of a macro that takes the size as input ($n:expr) and the initialization was [Zero::zero(), .. $n]. Is this use case no longer intended to be supported? On Nov 29, 2013 6:47 PM, Huon Wilson dbau...@gmail.com wrote: On 30/11/13 10:33, Ashish Myles wrote: Previously we had the Copy trait, which when implemented by trait T allowed one to write [Zero::zero(), ..SZ] where T implemented the Zero trait. But now I am not sure how to get that behavior. Concretely, here is the code I want to get compiling. (Just to check, I added both Clone and DeepClone, even though they don't automatically allow implicit copyability). use std::num::Zero; enum Constants { SZ = 2 } struct FooT([T, ..SZ]); implT : Clone + DeepClone + Zero FooT { pub fn new() - FooT { Foo([Zero::zero(), ..SZ]) } } The error I get is: error: copying a value of non-copyable type `T` tmp.rs:155 Foo([Zero::zero(), ..SZ]) Any way to do this? Or is this no longer supported for general types? Any intentions to add this behavior again? Otherwise, I can't even initialize my struct while being agnostic to the specific value of SZ. Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev Initialising a fixed size vector [T, ..n] by [foo(), .. n] unfortunately requires that `T` is implicitly copyable (that is, it doesn't move ownership when passed by value), and there's no way around this other than [foo(), foo(), foo(),...]. Huon ___ 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] deriving Clone on a struct with a static vector
On Sat, Jul 6, 2013 at 1:43 AM, Patrick Walton pwal...@mozilla.com wrote: On 7/5/13 10:42 PM, Ashish Myles wrote: And an additional question. 3. What is the rationale in having both Copy and Clone? Can one provide an exhaustive list for where one would want to use Copy instead of Clone/DeepClone? I tried to use clone everywhere, but I needed T : Copy + Zero to be able to write, for example, [Zero::zero(),.. 3] as in the following code I'm busy removing Copy from the language right now. Ah, thanks, then after your refactor, what trait would T : Zero need an implementation of to support [Zero::zero(),.. 3]? Clone? Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] deriving Clone on a struct with a static vector
On Sat, Jul 6, 2013 at 5:45 AM, Jason Fager jfa...@gmail.com wrote: I've started implementing traits for fixed-length vectors with a few macros: https://gist.github.com/jfager/5936197 I don't have Clone yet, but it should be easy to add. As a side note, looking through your code, this is cool: struct Foo([u8,..2]); Foo([1u8,2u8]) I had no idea one could define single-item/wrapper structs that way; i.e. like an anonymous member. This is going in my cool tidbits collection. Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Why separate equivalent impls for 'self [A], ~[A], @[A]
Perhaps this was an oversight as the code base has developed organically. But in case it was intentional, I just wanted to check. libstd/to_str.rs defines each of the following impls impl'self,A:ToStr ToStr for 'self [A] implA:ToStr ToStr for ~[A] implA:ToStr ToStr for @[A] whereas only the first one seems to be needed to cover all array cases. To test this, I defined an equivalent MyToStr trait, defining only the implementation for 'self [A], and it seemed to work for all the array types. So just to check: is there any particular reason one would want to define all three with identical implementation? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] deriving Clone on a struct with a static vector
1. The following code #[deriving(Clone)] struct V { v : [f64, ..3] } fn main() { } gives the following error tmp.rs:1:11: 1:16 error: mismatched types: expected `[f64, .. 3]` but found `[f64, .. 3]` (expected vector but found -ptr) tmp.rs:1 #[deriving(Clone)] Is this intended behavior or a bug? 2. Also, how does one now implement the Copy trait anymore? Using #[deriving Copy] currently gives the following error error: unknown `deriving` trait: `Copy` ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] deriving Clone on a struct with a static vector
And an additional question. 3. What is the rationale in having both Copy and Clone? Can one provide an exhaustive list for where one would want to use Copy instead of Clone/DeepClone? I tried to use clone everywhere, but I needed T : Copy + Zero to be able to write, for example, [Zero::zero(),.. 3] as in the following code struct VT { v : [T, ..3] } implT : Copy + Zero VT { pub fn new() - VT { V { v: [Zero::zero(), ..3] } } } (As the actual code was from a macro that was parametrized by the number of elements, I don't want to simply rewrite the initialization above as [Zero::zero(), Zero::zero(), Zero::zero()] to avoid the dependence on Copy.) ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust 0.7 prerelease testing
openSUSE 12.2 (i.e. previous release). make check succeeds: summary of 25 test runs: 5261 passed; 0 failed; 302 ignored ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust 0.7 prerelease testing
On Wed, Jul 3, 2013 at 4:00 PM, Ashish Myles marci...@gmail.com wrote: openSUSE 12.2 (i.e. previous release). make check succeeds: summary of 25 test runs: 5261 passed; 0 failed; 302 ignored To clarify, I did the check against trunk (0c6fc46c030ab0515a052fa99c9e10c75cfc8184), and my e-mail above was ~1hour after Brian's release announcement. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Borrow lifetime assignment changed?
Any idea why the following fails use std::{io,rand,task}; fn main() { for [Alice, Bob, Carol].iter().advance |name| { do task::spawn { use std::rand::RngUtil; let v = rand::rng().shuffle([1, 2, 3]); for v.iter().advance |num| { io::print(fmt!(%s says: '%d'\n, name, num)) } } } } with hello.rs:4:8: 4:33 error: borrowed value does not live long enough hello.rs:4 for [Alice, Bob, Carol].iter().advance |name| { ^ hello.rs:12:4: 12:5 note: borrowed pointer must be valid for the method call at 12:4... hello.rs:12 } ^ hello.rs:4:8: 4:41 note: ...but borrowed value is only valid for the method call at 4:8 hello.rs:4 for [Alice, Bob, Carol].iter().advance |name| { ^ error: aborting due to previous error Changing to let lst = [Alice, Bob, Carol]; for lst.iter().advance |name| { //... } succeeds, but I am surprised that the lifetime is not equivalent for lst and the raw vector literal for this specific code as there is nothing after the for-loop. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Front page example
Great, thanks, it works! Is there a way to invoke the shuffle() without bringing it explicitly into local scope, say via some verbose way that specifies the trait to be used? Ashish On Sat, Jun 22, 2013 at 11:00 PM, Huon Wilson dbau...@gmail.com wrote: On 23/06/13 12:53, Ashish Myles wrote: I have been out of rust for a bit, and coming back to it, I am having a difficult time adapting the front page example at http://www.rust-lang.org/ to the trunk version of rust (updated last night). I turned the example to use std::*; fn main() { for [Alice, Bob, Carol].each |name| { do task::spawn { let v = rand::rng().shuffle([1, 2, 3]); for v.each |num| { io::print(fmt!(%s says: '%d'\n, name, num)) } } } } and rustc complains with hello.rs:6:20: 6:51 error: type `std::rand::IsaacRng` does not implement any method in scope named `shuffle` hello.rs:6 let v = rand::rng().shuffle([1, 2, 3]); and a type inference error triggered by this part failing. In libstd/rand.rs, RngUtil seems to be defined for everything implementing Rng, which IsaacRng does. Is this a bug or is it some change in the lookup? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev To use the methods from a trait, it has to be in scope, so: use std::rand::{rng, RngUtil}; fn main() { for [Alice, Bob, Carol].each |name| { do spawn { let v = rng().shuffle([1, 2, 3]); for v.each |num| { print(fmt!(%s says: '%d'\n, name, num)) } } } } seems to work with my rustc (ba05af7 2013-06-20 22:28:52 -0700). (The reason many other traits don't need to be explicitly imported is that they are exported from std::prelude, which is implicitly added as `use std::prelude::*;` at the top of every mod.) Huon ___ 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] tjc's pre-talk and talk (was: This Week in Rust)
- tjc's pre-talk and talk, Rust: A Friendly Introduction went very well. The [slides](http://catamorphism.org/Writing/Rust-Tutorial-tjc.pdf) are up, and a recording is coming soon (hopefuly). tjc says the slides aren't as understanable without the audio of the talk. Thanks for the tutorial! The slides seem perfectly comprehensible without audio, except possibly for some points below that may either be corrected or perhaps addressed in the slide notes themselves. POSSIBLE ERRATA: Slide 40: The notes say Change [@Drawable] to [~@Drawable]. The latter should be ~[@Drawable], or, to be consistent with the Slide 41, perhaps [@Drawable]? Both tested to work. Slide 51: The program seems to be missing a unique pointer sigil ~; and the types of the array and the initializer (quux) don't match. Here is a possible correction? (Tested.) fn h(b: ~[int]) { } fn g(a: ~[int]) { } fn f(n: uint) { let v: ~[int] = vec::from_elem(n,1); h(v); g(v); } Slide 53: Perhaps the audio is needed for this slide, but I am confused. Before I start with that, I checked struct Cat { a : int, } fn main() { let v: Cat::new(); } It seems that there is no default new() function, so I don't know the type of the object returned by Cat::new(). Is it Cat or ~Cat here? The comment about Cat not being copyable seems to imply that the type is Cat (i.e. stack-allocated). But then send_cat_to_moon(cat) should not be able to invalidate the reference, right? So there should not be a problem with that code as webcam should get destructed before cat at the end of the block. If Cat::new() returns ~Cat and Webcam::new() returns ~Webcam, then I can see this working out, but then there is the implicit assumption (that could perhaps be clarified in the comments) that send_cat_to_moon(cat) takes its argument as ~Cat rather than, say, Cat. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Front page example
I have been out of rust for a bit, and coming back to it, I am having a difficult time adapting the front page example at http://www.rust-lang.org/ to the trunk version of rust (updated last night). I turned the example to use std::*; fn main() { for [Alice, Bob, Carol].each |name| { do task::spawn { let v = rand::rng().shuffle([1, 2, 3]); for v.each |num| { io::print(fmt!(%s says: '%d'\n, name, num)) } } } } and rustc complains with hello.rs:6:20: 6:51 error: type `std::rand::IsaacRng` does not implement any method in scope named `shuffle` hello.rs:6 let v = rand::rng().shuffle([1, 2, 3]); and a type inference error triggered by this part failing. In libstd/rand.rs, RngUtil seems to be defined for everything implementing Rng, which IsaacRng does. Is this a bug or is it some change in the lookup? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Macro bugs or misunderstanding of use?
Hi, I am running the rust compiler from trunk. My macro usage seems to be a macro_rules! my_print( ($a:expr, $b:expr) = ( io::println(fmt!(%d, a)); io::println(fmt!(%d, b)); ); ) fn main() { let a : int = 1; let b : int = 2; my_print!(a, b); } Compiling with rustc tmp.rs gives the following suspicious warning tmp.rs:10:8: 10:11 warning: unused variable: `b` tmp.rs:10 let b : int = 2; and ./tmp prints only 1. Running rustc tmp.rs --pretty expanded shows below that the second line io::println(fmt!(%d, b)); was ignored. fn main() { let a: int = 1; let b: int = 2; io::println({ let mut __fmtbuf = ~; ::unstable::extfmt::rt::conv_int(::unstable::extfmt::rt::Conv{flags: ::unstable::extfmt::rt::flag_none, width: ::unstable::extfmt::rt::CountImplied, precision: ::unstable::extfmt::rt::CountImplied, ty: ::unstable::extfmt::rt::TyDefault,}, a, mut __fmtbuf); __fmtbuf }); } Can someone point me in the right direction here? Also, can someone provide examples of how exactly log_syntax!() and trace_macros!(true) work? Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] How to use concat_idents! properly
So far, I have had a difficult time finding anything definitive on this except for some rust test code. fn main() { // PART 1: works (from rust test code) let asdf_fdsa = ~.; io::println(concat_idents!(asd, f_f, dsa)); io::println(stringify!(use_mention_distinction)); // PART 2: creating a function identifier fn concat_idents!(foo, _, bar) () { // fails to compile io::println(Foo!); } foo_bar(); // PART 3: a numeric is a bad identifier, but a good sub-identifier let asdf3 = ~.; io::println(concat_idents!(asdf, 3)); // fails to compile } The first part works fine. The second part, creating a function identifier seems a perfectly valid use-case, but fails compilation, and I don't know a valid work-around. I have been unable to find a similar usage anywhere. This third part was just some wishful thinking, actually, but if there are ways to do this directly (other than changing 3 to a valid identifier like N3), I would love to know. (Though, this might not longer have much of a use case if/when generics eventually support integral parameters.) Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How to use concat_idents! properly
On Sat, Mar 2, 2013 at 1:41 PM, Paul Stansifer paul.stansi...@gmail.com wrote: `concat_idents!` is currently broken, and it's my fault. Here's a discussion of how it might be fixed in the future: https://mail.mozilla.org/pipermail/rust-dev/2013-February/003170.html Sadly, there is no workaround. Perhaps it should be removed so that it stops confusing people? Paul Thanks. So am I to understand that this is a parsing issue -- in particular concat_idents!(...) doesn't parse like an ident? If so, since macros already use $ as special syntax for macro arguments, and there are only a handful of macro argument types, would it help for parsing if the macro argument types were made more accessible to the parser through specialized syntax? Chosen somewhat arbitrarily, one could use the following prefixes ident $$ expr $# ty $^ pat $~ block ${} so that macro arguments would be declared as $$i, $#j, $^T, etc. Then the type would be obvious to the parser and all operations between types could be language-implemented so that the parser understands the type of the expression it is dealing with. For example, concat_idents!() could be replaced by ${$$i + _ + $$j}, and the parser could happily accept it as a valid ident instead of requiring writing two macros when one should suffice. In the end, I could have something like: fn ${$$i + _ + $$j} () { io::println(ident_to_str!(${$$i + _ + $jj})) } The other types could similarly be composed: ($~p, ( $~q)) could be a composite pattern (unless patterns are already allowed to be composed to create new patterns; not checked). I couldn't come up with useful compositions of the other types that the parser would choke on. For example, it is not obvious that ident_to_str!() could be a cause for problems (for example if a string literal is expected by the parser). But if it were, $$$i or $${$$i + _ + $$j} could replace ident_to_str!($$i) or ident_to_str!(${$$i + _ + $$j}). Of course, I may be barking up the wrong tree and simply misunderstanding the underlying problem. Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] I wanted a dollar but you gave me a ... dollar?
On Sun, Feb 24, 2013 at 12:06 AM, Ashish Myles marci...@gmail.com wrote: On Fri, Feb 22, 2013 at 12:35 PM, John Clements cleme...@brinckerhoff.org wrote: On Feb 22, 2013, at 6:22 AM, Paul Stansifer wrote: Rust syntax expects a literal number in the `[T * n]` construct; from the parser's point of view, what it receives is an expression, without any information that it is a number. (There are internal reasons for this, but it also makes the behavior of `$` more consistent; for example, preventing Rust from having C's issue where everybody has to use lots of parentheses in macro definitions.) Implementing $n:integer in Rust is a possible solution, but not likely to happen very soon. Unfortunately, I can't think of a workaround that generates the same type. More or less as a note to myself and Paul: I claim that this problem would be solved by a token-tree-based macro system. John I just want to add for consideration: I hope the (eventually) implemented solution allows compile-time evaluable integer expressions for maximal expressivity. Same thing for $n:bool, etc, if implemented. Wait a sec...I guess we are barking up the wrong tree. The problem is not that rust macros don't support $n:integer, but that static array initialization seem to require a raw integer literal (possibly at the parsing level). One can imagine designing a statically-allocated matrix for size C1 x C2 that would allocate similar to: const C1 : int = 2; const C2 : int = 2; let a : [int * (C1*C2)] = [1,2,3,4]; But the code above gives the following error error: expected integral vector length but found `(` If this misbehavior were fixed, I think the macro system would not need to accommodate ints and other types specially, keeping it fundamentally simpler. I would think that anything that requires a compile-time integer should be able to receive a compile-time evaluable integer expression. Ideally, it would be great if Rust went further to allow something like let a : [int * choose(C1, C2)]; or const C3 = choose(C1, C2); let a : [int * C3]; where choose is a pure function that returns n-choose-k. Any thoughts? Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] I wanted a dollar but you gave me a ... dollar?
On Fri, Feb 22, 2013 at 12:35 PM, John Clements cleme...@brinckerhoff.org wrote: On Feb 22, 2013, at 6:22 AM, Paul Stansifer wrote: Rust syntax expects a literal number in the `[T * n]` construct; from the parser's point of view, what it receives is an expression, without any information that it is a number. (There are internal reasons for this, but it also makes the behavior of `$` more consistent; for example, preventing Rust from having C's issue where everybody has to use lots of parentheses in macro definitions.) Implementing $n:integer in Rust is a possible solution, but not likely to happen very soon. Unfortunately, I can't think of a workaround that generates the same type. More or less as a note to myself and Paul: I claim that this problem would be solved by a token-tree-based macro system. John I just want to add for consideration: I hope the (eventually) implemented solution allows compile-time evaluable integer expressions for maximal expressivity. Same thing for $n:bool, etc, if implemented. Thanks, Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Simple use of templates/generics compilation hassles
Well, I eventually figured out how to get things compiling, but it was highly non-obvious. I would appreciate it if someone could shed some light on why things behave this way so that I may learn to visually see the error. Say we have the following struct pub struct Vector3T { priv mut m_v: [T * 3] } 1. The following fails because it says it can't find T in the second line. pub pure fn fooT : Zero() - Vector3T { Vector3T { mut m_v: [Zero::zero(), Zero::zero(), Zero::zero()] } } Changing it to pub pure fn fooT : Zero() - Vector3T { Vector3 { mut m_v: [Zero::zero(), Zero::zero(), Zero::zero()] } } works. I had compared against core::DVec to avoid strange errors, but I seemed to have overlooked the lack of type in the constructor there. Why is the redundant inclusion of T bad? If anything it would allow the compiler to point out an error if the types didn't come out to be as intended. 2. Most of my other issues were multiple cases of this error. The following invocation of the function above fails with unresolved name: int let v = fooint(); Removing the explicit type specialization works, but requires an explicit type declaration to be unambiguous. let v : Vector3int = foo(); Why could I not be specific with the type parameter to the function? Is there an alternative meaning with which it clashed? Ashish ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Cloning managed memory between tasks?
I didn't much previous discussion on this topic on google. Sorry if I missed something and re-starting an old discussion. Here is an example from the manual of a standard lisp-style list. enum ListT { Nil, Cons(T, @ListT) } If one wished to move such a list to another task, a copy to unique pointers would be needed. But it seems that this data structure doesn't support any way of unique-ifying it, it would have to be copied to a transferable data structure (like ~[T]) and reconstructed on the other side. As converting to another container might not be as optimal for, say a tree or more complex data type, is there another way to deal with such a use-case? I see a serialization/de-serialization approach was suggested here: https://github.com/mozilla/rust/issues/3836 Perhaps, a viable alternative would be to have a cloning procedure (given two tasks specified) that creates managed memory only on the receiving side while cloning? Something like a copy to that task's heap and send it a pointer functionality ? Ashish ___ 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. implA: ToStr ~[A]: ToStr { // ... } rather than for all array types via ? implA: ToStr [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 Vector3T { 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 Vector3T { priv m_v: [mut T * 3] } implT Vector3T { 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 VectorTN ($name:ident, $n:expr) = ( struct Vector$nT { priv m_v: [mut T * $n]; } ); } ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Parametrizing traits by integers (or equivalent behavior)
Firstly, as this seems to be the only discussion mailing list for rust, I presumed that this might be a good place to ask newbie-ish questions. Please correct me if I am wrong. (I have previously played around with D, which has separate mailing lists for learners.) I am particularly interested in implementing and porting little utilities to try to get a better understanding of how well the type system supports (or gets in the way) of practical problems. I do understand rust is well in the alpha stage and I don't have any problems with rust modifications breaking my code. Secondly, I was wondering how one would go about writing a rust equivalent of the following C++ class for creating static-sized arrays interpreted as vectors. template typename T, int _N class Vector { public: enum { N = _N }; private: T m_v[N]; }; As traits are not parametrized by integers, and macros don't seem to be the right tool for this, is there some other language feature that could help me get a similar effect? Thanks. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev