Argh. I tried to do this. I’m going to just post my whole question as it has a pretty good compelling example:
Let’s say that I’m prototyping a new struct, and I can emulate it with
a Vec to get off the ground. I’d also like to expose an
iterator. That’s great, as I can just reuse the iter method from the
slice:
struct SparseArray(Vec<u8>);
impl SparseArray {
fn iter(&self) -> ??? {
self.0.iter()
}
}
A problem arises when I go to define the result type; I have to expose
that I’m using a slice iterator! I plan on implementing this using
something more suitable, so I don’t want consumers to actually know
that there’s a slice under the hood. Maybe my internal representation
will change a few times, so I want to hide the implementation details,
like a good programmer.
The best solution I am aware of is to create a newtype around
slice::Iter, but that presents a different challenge: now we have to
define the Iterator trait for the newtype:
struct SparseArrayIter<'a>(slice::Iter<'a, u8>);
impl<'a> Iterator for SparseArrayIter<'a> {
type Item = &'a u8;
fn next(&mut self) -> Option<&'a u8> { self.0.next() }
}
Yay! I’ve wrapped my iterator.
But I should probably wrap size_hint… oh, and it turns out that
nth has a specialized implementation so I should call it too. And
what about the other ~50 iterator methods?
A proposal
I’d like to be able to write something like this:
#[delegate(Iterator, to = "self.0")]
struct SparseArrayIter<'a>(slice::Iter<'a, u8>);
And the ever-helpful compiler can just write out all of those annoying
shim methods. I started a syntax extension to do this, but immediately
ran into a problem: there’s no way to get information about other
types.
So, what alternatives do we have? I think that an RFC is needed, in order to have a hook with the appropriate data available.
Note that I’ve used a trait here, but I think that conceptually it should work with delegating 1 or more methods to any field of a struct.
Inheritance for the sake of code reuse is a misuse of inheritance, certainly. However, inheritance does have a place, if you follow Liskov. However, you can’t really argue that by misusing inheritance, you do get code reuse very easily. This topic is all about having an equally-easy way to get reuse without having inheritance.
As does Haskell, as "generalized newtype deriving, if I understand correctly.