I'm beginning to suspect that I still don't understand the pivotal
differences between Traits and Interfaces. In particular, I think the
requires/provides idea in Traits isn't the crux of it. I'm beginning to
suspect that the more interesting part is the explicit binding that Traits
assumes.
Rather than debate labels, let me say what I envision for Interfaces in
BitC. If it turns out that this maps to Traits, I'll be happy to rename.
An interface definition defines a type. Instances of this type consist of
an (existential) managed pointer to some value (which may be a value type
or a reference type) and set of named method bindings, each of the form 'a
... 'z -> 'result. The invocation of a method "opens" the existential type
and passed the managed pointer as an additional leading parameter.
We clearly want a convenience syntax for default implementations, but from
a "core" perspective an Interface defines a class whose member types and
constructor arguments are constrained. In particular, the actual parameters
that bind the methods of the interface are constrained to be compile-time
evaluable expressions. This means, in practice, that:
- The method table can be implemented as a quasi-statically generated
compile-time constant, but
- Multiple variants of an interface can be produced for a single object.
- When the underlying object type is known at static compile time, the
compiler can elide the indirect dispatch of the interface mechanism,
- To some degree, interface implementations can act as type relation
witnesses in a similar way to type class implementations, and
- An interface consisting entirely of *static* methods (that is: methods
lacking a /this/ parameter) requires no /this/ pointer, and is very similar
to a type class declaration. In contrast to type classes, which are type
relations, an interface is a type.
I have a suspicion that the parallels between interfaces and type classes
may grow as we examine the implications of this definition. The difference,
I predict, will turn out to center around operator overload resolution
rather than types.
Syntactic sugar: an object can be declared as "implements IFace", and the
construction will be automatically be produced by name matching for
convenience. But this is merely convenience. An object can also declare an
interface generator in a style similar to attributes:
interface ReverseOrdering { return OrdInterface(this, >); }
Note that this quasi-attribute is compile-time evaluable. Note also that
this "interface attribute" need not appear within an object. A global
attribute of the form:
interface YetAnotherOrdering('type ob) { return OrdInterface(t, >); }
is perfectly valid.
Instances of interfaces are objects. This is necessary even for purely
static interface types because bindings are explicit.
An instance of an interface may not outlive the object that it references.
I'm sure there are half a dozen things I have omitted here, but this is at
least a starting point for discussion.
shap
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev