Hi Niko, Actually, after I sent this off I realized "... but I didn't really make any good points in favour of nominal interfaces at all".
I prefer them because they enforce a much more structured way of thinking. Declaring grab-bags of methods and assembling them into interfaces ad-hoc seems clumsy and, as you mention, error prone --- just because a method has a given name, doesn't mean it actually does the same thing as other methods by that name. Explicitly declaring what interface you're implementing would remove this vagueness. It also makes generating and reusing vtables easier -- most of them would only have to be generated once, and can be exported from the module that declares the category. Once we have categories / instances that depend on another type conforming to an interface, those'll have to be parameterized by the other type's vtable, so things get more tricky (much like our current dynamic tydescs). > - I don't see why every category must declare an associated interface. I > like the idea of *allowing* categories to declare associated interfaces, as > it will lead to better error reporting, but I think *requiring* it is too > much. It implies that the main purpose of a category is dynamic dispatch > and I am not sure that will be the case. I don't really see explicitly declared interfaces as having a lot, specifically, to do with dynamic dispatch. I you're right guess ad-hoc category declarations can be nice sometimes, especially since they allow post-hoc interop with code that wasn't written with any kind of interface in mind. But the latter can already be done by, once you've defined your interface, simply declaring an instance that calls the existing methods. Would you be satisfied with ad-hoc, interface-less methods that can only be called statically? > - I think the term instance ought to be reserved for runtime values You're probably right. But I'm not sure 'category' is much more helpful here. Maybe 'implementation'? (`impl`) > I am a bit > concerned about the definition of comparison and equality because they > really want to have two receiver types. Our == requires both operands to be of the same type. It seems all sane equality implementation have that property. However, there are two receive values, and we definitely don't want to end up writing foo.==(bar) or something awful like that. There are several ways to get around this by doing some surface-syntax-shuffling. But I think eventually we'll want to support both oo-method-style interfaces (written val.method(), used when there is clearly a single receiver), and functional-style interfaces (written method(arg, arg2), used when this is not the case). The resolution for the second type is actually easier to do. x == y could desugar to std::cmp::eq(x, y), or we could define some correspondence between infix ops and function names (which would remove the need for things like std::int::add and std::str::eq) the way Haskell does it. Best, Marijn _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
