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

Reply via email to