Re: [rust-dev] Porting some nesC features to rust?

2014-04-08 Thread Vladimir Pouzanov
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?

2014-04-08 Thread Corey Richardson
`&'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?

2014-04-08 Thread Vladimir Pouzanov
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?

2014-04-08 Thread Corey Richardson
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?

2014-04-08 Thread Vladimir Pouzanov
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

2014-04-08 Thread Kevin Ballard
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

2014-04-08 Thread Vladimir Pouzanov
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

2014-04-08 Thread Peter Marheine
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

2014-04-08 Thread Tommi Tissari
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