Re: [rust-dev] Porting some nesC features to rust?
Yes, in the end I decided to implement .data section copy over from flash to ram to get vtables :-) On Tue, Apr 8, 2014 at 7:34 PM, Corey Richardson wrote: > `&'static SPI` is going to be a trait object (with dynamic dispatch). > The error it's giving is that `&SPI` (the trait object) doesn't > implement `SPI` (the trait). You would have to explicitly implement > `SPI` for `&SPI`. I'm not really sure how to solve this without using > trait objects; you seem to want an inherently dynamically-dispatched > system. > > On Tue, Apr 8, 2014 at 2:08 PM, Vladimir Pouzanov > wrote: > > That actually worked much better than I expected inlining everything and > > getting rid of vtables (I don't have support for .data section at the > moment > > :-) ). > > > > I can't say the syntax is very clear to me, but I can get used to it. > Still, > > one more question remains. I have a "debug output" concept, which means > that > > debug::d("str") gets delivered to either LCD or UART, whatever is > configured > > at runtime. I do it via static mut: > > > > pub trait Debugger { > > fn debugs(&mut self, s: &str); > > } > > > > pub static mut debug_output: *mut c12332::C12332<'static, &'static > spi::SPI> > > = unsafe { init() }; > > > > pub fn d(s: &str) { > > let debugger = unsafe { &mut (*debug_output) as &mut Debugger }; // > failed > > to find an implementation of trait hal::spi::SPI for &'static > > hal::spi::SPI:'static > > debugger.debugs(s); > > } > > > > pub fn set_debugger(lcd: *mut c12332::C12332<&spi::SPI>) { > > unsafe { debug_output = lcd; }; > > } > > > > I don't really support UART now, but I'd still like to access my LCD via > a > > globally known static getter. How can I re-write that with typed struct? > > > > > > On Tue, Apr 8, 2014 at 6:26 PM, Corey Richardson > wrote: > >> > >> You don't use bounds in the struct, you put them in the impl. So you > >> would instead say > >> > >> > >> struct LCD { > >> spi: S, > >> ... > >> } > >> > >> > >> and then: > >> > >> impl LCD { > >> ... > >> } > >> > >> On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov > >> wrote: > >> > I might have found an unsupported case. > >> > > >> > Consider the following: > >> > > >> > trait SPI { ... } > >> > > >> > struct McuSPI; > >> > impl SPI for McuSPI { ... } > >> > > >> > struct LCD { > >> > spi: &SPI, > >> > ... > >> > } > >> > > >> > This code results in a dynamic dispatch to SPI, as "trait bounds are > not > >> > allowed in structure definitions". Is it in any way possible to use > >> > static > >> > dispatch from LCD to SPI given the exact implementations are known at > >> > compile time? > >> > > >> > > >> > On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles > wrote: > >> >> > >> >> 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 foo(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 > >> >> 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 min(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, > >> >> >> col
Re: [rust-dev] Porting some nesC features to rust?
`&'static SPI` is going to be a trait object (with dynamic dispatch). The error it's giving is that `&SPI` (the trait object) doesn't implement `SPI` (the trait). You would have to explicitly implement `SPI` for `&SPI`. I'm not really sure how to solve this without using trait objects; you seem to want an inherently dynamically-dispatched system. On Tue, Apr 8, 2014 at 2:08 PM, Vladimir Pouzanov wrote: > That actually worked much better than I expected inlining everything and > getting rid of vtables (I don't have support for .data section at the moment > :-) ). > > I can't say the syntax is very clear to me, but I can get used to it. Still, > one more question remains. I have a "debug output" concept, which means that > debug::d("str") gets delivered to either LCD or UART, whatever is configured > at runtime. I do it via static mut: > > pub trait Debugger { > fn debugs(&mut self, s: &str); > } > > pub static mut debug_output: *mut c12332::C12332<'static, &'static spi::SPI> > = unsafe { init() }; > > pub fn d(s: &str) { > let debugger = unsafe { &mut (*debug_output) as &mut Debugger }; // failed > to find an implementation of trait hal::spi::SPI for &'static > hal::spi::SPI:'static > debugger.debugs(s); > } > > pub fn set_debugger(lcd: *mut c12332::C12332<&spi::SPI>) { > unsafe { debug_output = lcd; }; > } > > I don't really support UART now, but I'd still like to access my LCD via a > globally known static getter. How can I re-write that with typed struct? > > > On Tue, Apr 8, 2014 at 6:26 PM, Corey Richardson wrote: >> >> You don't use bounds in the struct, you put them in the impl. So you >> would instead say >> >> >> struct LCD { >> spi: S, >> ... >> } >> >> >> and then: >> >> impl LCD { >> ... >> } >> >> On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov >> wrote: >> > I might have found an unsupported case. >> > >> > Consider the following: >> > >> > trait SPI { ... } >> > >> > struct McuSPI; >> > impl SPI for McuSPI { ... } >> > >> > struct LCD { >> > spi: &SPI, >> > ... >> > } >> > >> > This code results in a dynamic dispatch to SPI, as "trait bounds are not >> > allowed in structure definitions". Is it in any way possible to use >> > static >> > dispatch from LCD to SPI given the exact implementations are known at >> > compile time? >> > >> > >> > On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles wrote: >> >> >> >> 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 foo(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 >> >> 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 min(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:
Re: [rust-dev] Porting some nesC features to rust?
That actually worked much better than I expected inlining everything and getting rid of vtables (I don't have support for .data section at the moment :-) ). I can't say the syntax is very clear to me, but I can get used to it. Still, one more question remains. I have a "debug output" concept, which means that debug::d("str") gets delivered to either LCD or UART, whatever is configured at runtime. I do it via static mut: pub trait Debugger { fn debugs(&mut self, s: &str); } pub static mut debug_output: *mut c12332::C12332<'static, &'static spi::SPI> = unsafe { init() }; pub fn d(s: &str) { let debugger = unsafe { &mut (*debug_output) as &mut Debugger }; // failed to find an implementation of trait hal::spi::SPI for &'static hal::spi::SPI:'static debugger.debugs(s); } pub fn set_debugger(lcd: *mut c12332::C12332<&spi::SPI>) { unsafe { debug_output = lcd; }; } I don't really support UART now, but I'd still like to access my LCD via a globally known static getter. How can I re-write that with typed struct? On Tue, Apr 8, 2014 at 6:26 PM, Corey Richardson wrote: > You don't use bounds in the struct, you put them in the impl. So you > would instead say > > > struct LCD { > spi: S, > ... > } > > > and then: > > impl LCD { > ... > } > > On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov > wrote: > > I might have found an unsupported case. > > > > Consider the following: > > > > trait SPI { ... } > > > > struct McuSPI; > > impl SPI for McuSPI { ... } > > > > struct LCD { > > spi: &SPI, > > ... > > } > > > > This code results in a dynamic dispatch to SPI, as "trait bounds are not > > allowed in structure definitions". Is it in any way possible to use > static > > dispatch from LCD to SPI given the exact implementations are known at > > compile time? > > > > > > On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles wrote: > >> > >> 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 foo(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 > >> 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 min(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 dir
Re: [rust-dev] Porting some nesC features to rust?
You don't use bounds in the struct, you put them in the impl. So you would instead say struct LCD { spi: S, ... } and then: impl LCD { ... } On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov wrote: > I might have found an unsupported case. > > Consider the following: > > trait SPI { ... } > > struct McuSPI; > impl SPI for McuSPI { ... } > > struct LCD { > spi: &SPI, > ... > } > > This code results in a dynamic dispatch to SPI, as "trait bounds are not > allowed in structure definitions". Is it in any way possible to use static > dispatch from LCD to SPI given the exact implementations are known at > compile time? > > > On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles wrote: >> >> 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 foo(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 >> 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 min(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@mozi
Re: [rust-dev] Porting some nesC features to rust?
I might have found an unsupported case. Consider the following: trait SPI { ... } struct McuSPI; impl SPI for McuSPI { ... } struct LCD { spi: &SPI, ... } This code results in a dynamic dispatch to SPI, as "trait bounds are not allowed in structure definitions". Is it in any way possible to use static dispatch from LCD to SPI given the exact implementations are known at compile time? On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles wrote: > 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 foo(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 > 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 min(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 > > > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] impl num::Zero and std::ops::Add error
On Apr 7, 2014, at 1:02 AM, Tommi Tissari wrote: > On 07 Apr 2014, at 08:44, Nicholas Radford wrote: > >> I think the original question was, why does the zero trait require the add >> trait. >> > If that was the original question, then my answer would be that > std::num::Zero requires the Add trait because of the way it is specified: > "Defines an additive identity element for Self". Then the question becomes: > "why is Zero specified like that?", and I would answer: because then you can > use it in generic algorithms which require their argument(s) to have an > additional identity. If you want a zero value for a type that doesn't support addition, std::default::Default may be a good choice to use. Semantically, that actually returns the "default value" for a type instead of the "zero value", but in a type without addition, how do you define "zero value"? -Kevin___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] matching on a few bits in int
Awesome use of unreachable! On Tue, Apr 8, 2014 at 4:53 PM, Peter Marheine wrote: > I had a go at building a macro to do this sort of thing, and it turned > out to be easier than I expected. > > https://gist.github.com/tari/10144385 > > Use like this: > let x = match_bitfield!(do_something(), bits 4 to 8 { > 0 => DivideBy1, > 1 => DivideBy2, > 2 => DivideBy4, > _ => UnknownDivisor > }; > > On Fri, Apr 4, 2014 at 7:11 AM, Vladimir Pouzanov > wrote: > > I've submitted an RFC for this one: > > https://github.com/rust-lang/rfcs/pull/29 > > > > > > On Sat, Mar 29, 2014 at 6:14 PM, Bill Myers > wrote: > >> > >> I think the best solution is to add uN and sN types where N is not a > power > >> of two, which LLVM should already support. > >> > >> Then you can write your match like this: > >> match (val >> 6) as u2 > >> { > >> ... > >> } > >> > >> And it will work as desired. > >> > >> Biggest issue is that to make it work nicely you'd need to add some way > to > >> generalize over the bit-length and integers, and that's going to require > >> generics with int parameters and work to add those. > >> > > > > > > > > -- > > Sincerely, > > Vladimir "Farcaller" Pouzanov > > http://farcaller.net/ > > > > ___ > > Rust-dev mailing list > > Rust-dev@mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > > > > -- > Peter Marheine > Don't Panic > -- Sincerely, Vladimir "Farcaller" Pouzanov http://farcaller.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] matching on a few bits in int
I had a go at building a macro to do this sort of thing, and it turned out to be easier than I expected. https://gist.github.com/tari/10144385 Use like this: let x = match_bitfield!(do_something(), bits 4 to 8 { 0 => DivideBy1, 1 => DivideBy2, 2 => DivideBy4, _ => UnknownDivisor }; On Fri, Apr 4, 2014 at 7:11 AM, Vladimir Pouzanov wrote: > I've submitted an RFC for this one: > https://github.com/rust-lang/rfcs/pull/29 > > > On Sat, Mar 29, 2014 at 6:14 PM, Bill Myers wrote: >> >> I think the best solution is to add uN and sN types where N is not a power >> of two, which LLVM should already support. >> >> Then you can write your match like this: >> match (val >> 6) as u2 >> { >> ... >> } >> >> And it will work as desired. >> >> Biggest issue is that to make it work nicely you'd need to add some way to >> generalize over the bit-length and integers, and that's going to require >> generics with int parameters and work to add those. >> > > > > -- > Sincerely, > Vladimir "Farcaller" Pouzanov > http://farcaller.net/ > > ___ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- Peter Marheine Don't Panic ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Tagged integral & floating-point types
I just realized that this 'Invalid' trait is also a prime example of why traits must be able to specify their items as private. Obviously that 'invalid' static method / constant should not be part of the public interface. Heck, the sole reason for the existence of the type could be that it protects itself from becoming invalid. And I'd also argue that private should be the default for the items specified by traits so that there's no need for 'priv' keyword. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev