Re: [rust-dev] Strange behavior about Writer trait

2013-10-20 Thread Oren Ben-Kiki
I'm not sure I follow.

Assuming that the trait `T` has no method that uses `Self`, then any `impl`
requiring `T` should happily accept an `T` / `@T`. Why penalize
non-self-referential traits (like `Writer`), just because some traits (like
`AdderIncr`) are self-referential?

On Sun, Oct 20, 2013 at 1:10 AM, Steven Blenkinsop steven...@gmail.comwrote:

 Consider this program:

 
 trait AdderIncr {
 fn add(self, x: Self) - Self;
 fn incr(mut self);
 }

 impl AdderIncr for int {
 fn add(self, x: int) - int { *self + x }
 fn incr(mut self) { *self += 1; }
 }

 fn incrAdd(x: mut AdderIncr, y: mut AdderIncr) {
 x.incr();
 x.add(y);
 }

 fn main() {}
 

 It fails to compile:

 
 Documents/test.rs:13:1: 13:10 error: cannot call a method whose type
 contains a self-type through an object
 Documents/test.rs:13x.add(y);
 ^
 

 The Self type is meaningless in object methods, since I have no way to
 ensure that y has the same underlying type as x. Thus, only a subset of the
 methods of a trait are available on the corresponding object, which means
 that objects can't automatically implement their corresponding trait.

 That means any impls that implement a trait for all types that implement
 AdderIncr, for example, won't implement that trait for AdderIncr, since
 AdderIncr doesn't implement AdderIncr.

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


[rust-dev] Strange behavior about Writer trait

2013-10-19 Thread Oren Ben-Kiki
I run into the following problem (the code below is a toy example).

```
use std::io::Writer; // Makes no difference if added/removed.

trait PrintWithSpice {
fn print(self, writer: Writer, spice: bool);
}

struct Bar {
bar: ~PrintWithSpice,
}

impl Bar {
pub fn print(self, writer: Writer) {
self.bar.print(writer, false);
Bar::print_via_borrowed(writer, self.bar);
}

fn print_via_borrowed(writer: Writer, data: PrintWithSpice) {
// Invoking the `print` function via the borrowed pointer to the
`PrintWithSpice` trait:
// Works fine, as expected..
data.print(writer, true);
}
}

struct Foo {
foo: bool
}

impl PrintWithSpice for Foo {
fn print(self, writer: Writer, spice: bool) {
// Invoking the `write_str` function via the borrowed pointer to
the `Writer` trait:
// error: failed to find an implementation of trait std::io::Writer
for std::io::Writerno-bounds
// What is going on?
writer.write_str(format!(foo: {:b} spice: {:b}, self.foo, spice));
}
}
```

I didn't understand what the compiler is complaining about. failed to find
an implementation of Foo for Foono-bounds? A Foo is a Foo, no? Calling
a function via a borrowed pointer to a trait should just work (it does a
few lines above).

After digging I discovered what the compiler really meant (I think). The
`write_str` method is defined for `WriterUtils` rather than for `Writer`.
So, if I replace `Writer` by `WriterUtil` in the above code, it compiles
fine.

So, I ended up defining `trait MyWriter: Writer + WriterUtil` and I am
using that instead of `Writer` all over my code. I can see doing that as a
workaround, but it doesn't smell right to me.

So:

* Why is the compiler complaining about not finding an implementation for
`Writer` when the method I invoke is from `WriterUtil`?

* Since there is an `implT: Writer for WriterUtil`, shouldn't the
compiler be sufficiently smart to deduce that the code is valid in the
1st place?

* Until the compiler is sufficiently smart (or, if there is a good reason
why it would never be), shouldn't we rename `Writer` to `BasicWriter` and
define `trait Writer: BasicWriter, WriterUtil {}` so `Writer` would become
more usable?
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Strange behavior about Writer trait

2013-10-19 Thread Oren Ben-Kiki
Ugh, I was too optimistic. Yes, I can write my code using `MyWriter`, but I
can't cast any @Writer (such as `io::stdout()`) to it. I guess I should
just use `@Writer` everywhere for now :-(

This raises the question of how come the compiler is smart enough to figure
out a `@Writer` has the trait `WriterUtil`, but isn't smart enough to
figure out a `Writer` has the trait...


On Sat, Oct 19, 2013 at 9:08 AM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 I run into the following problem (the code below is a toy example).

 ```
 use std::io::Writer; // Makes no difference if added/removed.

 trait PrintWithSpice {
 fn print(self, writer: Writer, spice: bool);
 }

 struct Bar {
 bar: ~PrintWithSpice,
 }

 impl Bar {
 pub fn print(self, writer: Writer) {
 self.bar.print(writer, false);
 Bar::print_via_borrowed(writer, self.bar);
 }

 fn print_via_borrowed(writer: Writer, data: PrintWithSpice) {
 // Invoking the `print` function via the borrowed pointer to the
 `PrintWithSpice` trait:
 // Works fine, as expected..
 data.print(writer, true);
 }
 }

 struct Foo {
 foo: bool
 }

 impl PrintWithSpice for Foo {
 fn print(self, writer: Writer, spice: bool) {
 // Invoking the `write_str` function via the borrowed pointer to
 the `Writer` trait:
 // error: failed to find an implementation of trait
 std::io::Writer for std::io::Writerno-bounds
 // What is going on?
 writer.write_str(format!(foo: {:b} spice: {:b}, self.foo,
 spice));
 }
 }
 ```

 I didn't understand what the compiler is complaining about. failed to
 find an implementation of Foo for Foono-bounds? A Foo is a Foo, no?
 Calling a function via a borrowed pointer to a trait should just work (it
 does a few lines above).

 After digging I discovered what the compiler really meant (I think). The
 `write_str` method is defined for `WriterUtils` rather than for `Writer`.
 So, if I replace `Writer` by `WriterUtil` in the above code, it compiles
 fine.

 So, I ended up defining `trait MyWriter: Writer + WriterUtil` and I am
 using that instead of `Writer` all over my code. I can see doing that as a
 workaround, but it doesn't smell right to me.

 So:

 * Why is the compiler complaining about not finding an implementation for
 `Writer` when the method I invoke is from `WriterUtil`?

 * Since there is an `implT: Writer for WriterUtil`, shouldn't the
 compiler be sufficiently smart to deduce that the code is valid in the
 1st place?

 * Until the compiler is sufficiently smart (or, if there is a good
 reason why it would never be), shouldn't we rename `Writer` to
 `BasicWriter` and define `trait Writer: BasicWriter, WriterUtil {}` so
 `Writer` would become more usable?

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


Re: [rust-dev] Strange behavior about Writer trait

2013-10-19 Thread Steven Fackler
If T is a trait, its trait objects ~T, @T and T do not implement T. There
is an implementation of Writer for @Writer, but not for ~Writer or Writer
which is why you're seeing that error.

Steven Fackler


On Fri, Oct 18, 2013 at 11:27 PM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 Ugh, I was too optimistic. Yes, I can write my code using `MyWriter`, but
 I can't cast any @Writer (such as `io::stdout()`) to it. I guess I should
 just use `@Writer` everywhere for now :-(

 This raises the question of how come the compiler is smart enough to
 figure out a `@Writer` has the trait `WriterUtil`, but isn't smart enough
 to figure out a `Writer` has the trait...


 On Sat, Oct 19, 2013 at 9:08 AM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 I run into the following problem (the code below is a toy example).

 ```
 use std::io::Writer; // Makes no difference if added/removed.

 trait PrintWithSpice {
 fn print(self, writer: Writer, spice: bool);
 }

 struct Bar {
 bar: ~PrintWithSpice,
 }

 impl Bar {
 pub fn print(self, writer: Writer) {
 self.bar.print(writer, false);
 Bar::print_via_borrowed(writer, self.bar);
 }

 fn print_via_borrowed(writer: Writer, data: PrintWithSpice) {
 // Invoking the `print` function via the borrowed pointer to the
 `PrintWithSpice` trait:
 // Works fine, as expected..
 data.print(writer, true);
 }
 }

 struct Foo {
 foo: bool
 }

 impl PrintWithSpice for Foo {
 fn print(self, writer: Writer, spice: bool) {
 // Invoking the `write_str` function via the borrowed pointer to
 the `Writer` trait:
 // error: failed to find an implementation of trait
 std::io::Writer for std::io::Writerno-bounds
 // What is going on?
 writer.write_str(format!(foo: {:b} spice: {:b}, self.foo,
 spice));
 }
 }
 ```

 I didn't understand what the compiler is complaining about. failed to
 find an implementation of Foo for Foono-bounds? A Foo is a Foo, no?
 Calling a function via a borrowed pointer to a trait should just work (it
 does a few lines above).

 After digging I discovered what the compiler really meant (I think). The
 `write_str` method is defined for `WriterUtils` rather than for `Writer`.
 So, if I replace `Writer` by `WriterUtil` in the above code, it compiles
 fine.

 So, I ended up defining `trait MyWriter: Writer + WriterUtil` and I am
 using that instead of `Writer` all over my code. I can see doing that as a
 workaround, but it doesn't smell right to me.

 So:

 * Why is the compiler complaining about not finding an implementation for
 `Writer` when the method I invoke is from `WriterUtil`?

 * Since there is an `implT: Writer for WriterUtil`, shouldn't the
 compiler be sufficiently smart to deduce that the code is valid in the
 1st place?

 * Until the compiler is sufficiently smart (or, if there is a good
 reason why it would never be), shouldn't we rename `Writer` to
 `BasicWriter` and define `trait Writer: BasicWriter, WriterUtil {}` so
 `Writer` would become more usable?



 ___
 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] Strange behavior about Writer trait

2013-10-19 Thread Oren Ben-Kiki
Hmmm That sounds strange. Shouldn't `obj: T` allow me to invoke
`obj.method_of_T()`?

For example, how did I manage to invoke the `data.print(...)` method via
the borrowed `data: PrintWithSpice` pointer? Automatic dereference? And if
so, why didn't it work for `Writer` as well?

On Sat, Oct 19, 2013 at 9:29 AM, Steven Fackler sfack...@gmail.com wrote:

 If T is a trait, its trait objects ~T, @T and T do not implement T. There
 is an implementation of Writer for @Writer, but not for ~Writer or Writer
 which is why you're seeing that error.

 Steven Fackler


 On Fri, Oct 18, 2013 at 11:27 PM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 Ugh, I was too optimistic. Yes, I can write my code using `MyWriter`, but
 I can't cast any @Writer (such as `io::stdout()`) to it. I guess I should
 just use `@Writer` everywhere for now :-(

 This raises the question of how come the compiler is smart enough to
 figure out a `@Writer` has the trait `WriterUtil`, but isn't smart enough
 to figure out a `Writer` has the trait...


 On Sat, Oct 19, 2013 at 9:08 AM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 I run into the following problem (the code below is a toy example).

 ```
 use std::io::Writer; // Makes no difference if added/removed.

 trait PrintWithSpice {
 fn print(self, writer: Writer, spice: bool);
 }

 struct Bar {
 bar: ~PrintWithSpice,
 }

 impl Bar {
 pub fn print(self, writer: Writer) {
 self.bar.print(writer, false);
 Bar::print_via_borrowed(writer, self.bar);
 }

 fn print_via_borrowed(writer: Writer, data: PrintWithSpice) {
 // Invoking the `print` function via the borrowed pointer to the
 `PrintWithSpice` trait:
 // Works fine, as expected..
 data.print(writer, true);
 }
 }

 struct Foo {
 foo: bool
 }

 impl PrintWithSpice for Foo {
 fn print(self, writer: Writer, spice: bool) {
 // Invoking the `write_str` function via the borrowed pointer to
 the `Writer` trait:
 // error: failed to find an implementation of trait
 std::io::Writer for std::io::Writerno-bounds
 // What is going on?
 writer.write_str(format!(foo: {:b} spice: {:b}, self.foo,
 spice));
 }
 }
 ```

 I didn't understand what the compiler is complaining about. failed to
 find an implementation of Foo for Foono-bounds? A Foo is a Foo, no?
 Calling a function via a borrowed pointer to a trait should just work (it
 does a few lines above).

 After digging I discovered what the compiler really meant (I think). The
 `write_str` method is defined for `WriterUtils` rather than for `Writer`.
 So, if I replace `Writer` by `WriterUtil` in the above code, it compiles
 fine.

 So, I ended up defining `trait MyWriter: Writer + WriterUtil` and I am
 using that instead of `Writer` all over my code. I can see doing that as a
 workaround, but it doesn't smell right to me.

 So:

 * Why is the compiler complaining about not finding an implementation
 for `Writer` when the method I invoke is from `WriterUtil`?

 * Since there is an `implT: Writer for WriterUtil`, shouldn't the
 compiler be sufficiently smart to deduce that the code is valid in the
 1st place?

 * Until the compiler is sufficiently smart (or, if there is a good
 reason why it would never be), shouldn't we rename `Writer` to
 `BasicWriter` and define `trait Writer: BasicWriter, WriterUtil {}` so
 `Writer` would become more usable?



 ___
 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] Strange behavior about Writer trait

2013-10-19 Thread Steven Blenkinsop
Consider this program:


trait AdderIncr {
fn add(self, x: Self) - Self;
fn incr(mut self);
}

impl AdderIncr for int {
fn add(self, x: int) - int { *self + x }
fn incr(mut self) { *self += 1; }
}

fn incrAdd(x: mut AdderIncr, y: mut AdderIncr) {
x.incr();
x.add(y);
}

fn main() {}


It fails to compile:


Documents/test.rs:13:1: 13:10 error: cannot call a method whose type
contains a self-type through an object
Documents/test.rs:13x.add(y);
^


The Self type is meaningless in object methods, since I have no way to
ensure that y has the same underlying type as x. Thus, only a subset of the
methods of a trait are available on the corresponding object, which means
that objects can't automatically implement their corresponding trait.

That means any impls that implement a trait for all types that implement
AdderIncr, for example, won't implement that trait for AdderIncr, since
AdderIncr doesn't implement AdderIncr.



On Sat, Oct 19, 2013 at 2:47 AM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 Hmmm That sounds strange. Shouldn't `obj: T` allow me to invoke
 `obj.method_of_T()`?

 For example, how did I manage to invoke the `data.print(...)` method via
 the borrowed `data: PrintWithSpice` pointer? Automatic dereference? And if
 so, why didn't it work for `Writer` as well?

 On Sat, Oct 19, 2013 at 9:29 AM, Steven Fackler sfack...@gmail.comwrote:

 If T is a trait, its trait objects ~T, @T and T do not implement T.
 There is an implementation of Writer for @Writer, but not for ~Writer or
 Writer which is why you're seeing that error.

 Steven Fackler


 On Fri, Oct 18, 2013 at 11:27 PM, Oren Ben-Kiki o...@ben-kiki.orgwrote:

 Ugh, I was too optimistic. Yes, I can write my code using `MyWriter`,
 but I can't cast any @Writer (such as `io::stdout()`) to it. I guess I
 should just use `@Writer` everywhere for now :-(

 This raises the question of how come the compiler is smart enough to
 figure out a `@Writer` has the trait `WriterUtil`, but isn't smart enough
 to figure out a `Writer` has the trait...


 On Sat, Oct 19, 2013 at 9:08 AM, Oren Ben-Kiki o...@ben-kiki.orgwrote:

 I run into the following problem (the code below is a toy example).

 ```
 use std::io::Writer; // Makes no difference if added/removed.

 trait PrintWithSpice {
 fn print(self, writer: Writer, spice: bool);
 }

 struct Bar {
 bar: ~PrintWithSpice,
 }

 impl Bar {
 pub fn print(self, writer: Writer) {
 self.bar.print(writer, false);
 Bar::print_via_borrowed(writer, self.bar);
 }

 fn print_via_borrowed(writer: Writer, data: PrintWithSpice) {
 // Invoking the `print` function via the borrowed pointer to
 the `PrintWithSpice` trait:
 // Works fine, as expected..
 data.print(writer, true);
 }
 }

 struct Foo {
 foo: bool
 }

 impl PrintWithSpice for Foo {
 fn print(self, writer: Writer, spice: bool) {
 // Invoking the `write_str` function via the borrowed pointer
 to the `Writer` trait:
 // error: failed to find an implementation of trait
 std::io::Writer for std::io::Writerno-bounds
 // What is going on?
 writer.write_str(format!(foo: {:b} spice: {:b}, self.foo,
 spice));
 }
 }
 ```

 I didn't understand what the compiler is complaining about. failed to
 find an implementation of Foo for Foono-bounds? A Foo is a Foo, no?
 Calling a function via a borrowed pointer to a trait should just work (it
 does a few lines above).

 After digging I discovered what the compiler really meant (I think).
 The `write_str` method is defined for `WriterUtils` rather than for
 `Writer`. So, if I replace `Writer` by `WriterUtil` in the above code, it
 compiles fine.

 So, I ended up defining `trait MyWriter: Writer + WriterUtil` and I am
 using that instead of `Writer` all over my code. I can see doing that as a
 workaround, but it doesn't smell right to me.

 So:

 * Why is the compiler complaining about not finding an implementation
 for `Writer` when the method I invoke is from `WriterUtil`?

 * Since there is an `implT: Writer for WriterUtil`, shouldn't the
 compiler be sufficiently smart to deduce that the code is valid in the
 1st place?

 * Until the compiler is sufficiently smart (or, if there is a good
 reason why it would never be), shouldn't we rename `Writer` to
 `BasicWriter` and define `trait Writer: BasicWriter, WriterUtil {}` so
 `Writer` would become more usable?



 ___
 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