[rust-dev] Traits proposal
pwalton at mozilla.com
Fri Jul 6 19:02:30 PDT 2012
On 7/6/12 6:47 PM, Sebastian Sylvan wrote:
> This seems.. quite painful. I would be extremely unlikely to use a
> 'hash' trait in a hash table implementation for this reason. I'd store
> the hash function as a closure in the table itself, and set it up at
> construction (this way you can pass in any hash function provider at
> construction). It almost seems like the guidance for library writers
> would be to avoid traits because they reduce the ability for users to
> compose different behaviors (or at the very least each library would
> provide two versions of everything - one which uses a trait, and one
> which takes the method dictionary at construction time and stores it
> with the data structure).
Yes, it's a drawback. I think Haskell's "sort" and "sortBy" pairs of
functions are an okay solution (which is basically what you're
proposing), although not optimal. Most of the time you use the trait
version of the hash table; in the case in which you need a non-default
hash function, you use the virtually-dispatched version.
Keep in mind that named impls (as implemented now, and as proposed for
Haskell) don't really solve the hash table problem, though; if I
instantiate a hash table and call insert() with the trait instantiated
for str with FastHash, then I might pass that hash table to someone else
who calls get() with the trait instantiated for str at QuickHash.
Niko has proposed a general solution, which is basically a refined
version of the newtype proposal: allow types to be refined with trait
implementations. So a hash table might have type
HashMap<str:QuickHash,int>. This is closely related to just wrapping str
in a newtype, with better ergonomics.
I think the system as proposed could be extended to accommodate this if
it proves necessary; you would essentially have named implementations
(or newtypes, if you prefer to look at it that way) that you could wrap
values in and get out a wrapped version with different trait
implementations. These wrapped types could be treated as true subtypes,
so that coercion back and forth is free.
But it seems to me that it's worth trying the proposed system and seeing
how expressive it turns out to be in practice; we can always layer the
more sophisticated system on top in the future without breaking
anything. The ergonomic benefits of not having to import implementations
in the common case makes coherence worth it, I think.
More information about the Rust-dev