http://repetae.net/john/recent/out/supertyping.html

This was a passing proposal to allow supertype declarations in
Haskell.  I'm referencing it here because it's something that I've had
in the back of my mind for a while for Perl 6.  I'm glad somebody else
has thought of it.

Something that is worth looking into is Sather's type system.  I
haven't read anything about it yet, but worry not, I will.

Anyway, on to the proposal.

I've often thought that it would be very powerful to put types
in-between other types in the hierarchy.  This includes making
existing types do your roles (which Damian describes as "spooky action
at a distance").  Allow me to provide an example.

Let's say that Perl 6 does not provide a complex number class by
default.  How would you go about writing one?  Well, let's do the
standard Perl practice of making words that your users are supposed to
say in their code roles.

    role Complex { 
        # implementation details are unimportant (as always :-p)
    }

Now, where does it belong in the type heirarcy so it can interact well
with standard types?  It belongs *above* Num (and below whatever is
above Num).  Everything that is a Num is a Complex right?  It just has
a zero imaginary part.  But currently that is impossible.  So we have
to define conversions, which behave quite differently from simple
interface compatibilites.  For one, we have to reference a concrete
complex type.  Basically, we've made Complex feel like an outsider to
the Perl standard hierarchy.

As another example, let's say I'm implementing my own Junction class,
MyJunction.  I want it to be lower precedence than standard Junctions
(for an appropriate definition of precedence; in this case, it means
it will be threaded first).  Put aside for the moment how we define
the multimethods for all existing subs at once.

The safe way to implement a threading object is to give it its own
level in the type hierarchy.  For example, to do Junction, we
structure the type hierarchy like so:

    Any
    |- Junction
    |- JunctionObject   # or some other appropriate name
       |- Object
          |- ...

Then we can safely define MMD variants and be sure that they won't
change their semantics when derivation levels change under manhattan
distance.  Under pure ordering, we prevent against ambiguity errors
(which is in fact how I came up with this pattern).

So, anyway, to define MyJunction, I'd like the hierarchy to look like this:

    Any
    |- MyJunction
    |- MyJunctionObject
       |- Junction
       |- JunctionObject
          |- Object
             |- ...

This is a case where it is absolutely necessary to supertype in order
to achieve certain semantics.

Okay, now that I have the need out of the way, the syntax is obvious:

    role Complex
        does Object
        contains Num
    {...}

There is probably a better word than "contains".  I was thinking set
theory when I came up with that one.

It might be wise only to allow this for roles if we go with a
derivation metric-based MMD scheme.  Allowing this for classes would
mean that you could add depth to the metric that the author of the
classes in question didn't intend, and I've already shown that you can
screw up manhattan MMD semantics at a distance, spookily, if you do
that.

Luke

Reply via email to