On Wed, Dec 13, 2006 at 11:13:32PM -0800, Jonathan Lang wrote:
: Unfortunately, this approach completely misses the boat in terms of
: what I was looking for in supertyping - namely, the ability to reuse
: portions of an existing interface (such as the aforementioned "extract
: an Order role out of the Num role") - useful when using modules where
: the module designer overcomplicated things, but you don't want to
: rebuild everything from scratch.  That, I think, is the common feature
: of both goals: the ability to compensate for another coder who didn't
: do things exactly the way you want them done, but who was reasonably
: close.

I've been sloshing all this through my muddled head again, and I'm
beginning to see this as more of a naming policy issue, that is, an
authority issue.  The problem with "done_by" is that you're modifying
something in place, which mixes up the one name to mean two different
things.  But this sort of problem is almost exactly what the naming
authority was added for.  Suppose JRANDOM's version of Num says:

    role Num-1.3-JRANDOM does OUTER::Num does Complex;
    method re (--> OUTER::Num) { self }
    method im (--> OUTER::Num) { 0.0 }

Then if you say

    use Num-1.3-JRANDOM;

then for the rest of your lexical scope, Num is known to do Complex,
without backediting of the standard Num role.  The only "downside"
I can see is lack of Magical Action at a Distance--other lexical
scopes will also have to declare the Num alias, either directly or
via a policy module.

The OUTER:: notation above is negotiable.  I originally had Num-*-STD
but that gets a bit odd when you want to say:

    role Num-1.3-JRANDOM does Num-*-STD does Complex;
    method re (--> Num-*-STD) { self }
    method im (--> Num-*-STD) { 0.0 }

insofar as it visually implies a * every time, and in theory each *
could resolve to a different version number if the compiler was really
slow and the library updater was really fast.  One can get rid of that
visual impression by saying

    role Num-1.3-JRANDOM does Num-6-STD does Complex;
    method re (--> Num-6-STD) { self }
    method im (--> Num-6-STD) { 0.0 }

though that's still effectively wildcarded for versions of Perl 6.*.*.
I also thought about just saying:

    role Num-1.3-JRANDOM does perl6:Num does Complex;
    method re (--> perl6:Num) { self }
    method im (--> perl6:Num) { 0.0 }

but that seems wrong.  The perl6: prefix denotes the current namespace,
not the standard namespace, so since declarations insert their name
immediately in Perl 6, the new role Num-1.3-JRANDOM would already
be installed such that you could say perl6:Num-1.3-JRANDOM, and
arguably perl6:Num could select our own name instead of Num-6.0.2-STD.
That would seem to depend on site policy not globally overriding STD
with JRANDOM.  In any event, this certainly can't work:

    role Num-1.3-JRANDOM does Num does Complex;
    method re (--> Num) { self }
    method im (--> Num) { 0.0 }

because Num is already aliased to Num-1.3-JRANDOM by then.  So that's
why I ended up using OUTER::.  However, in the spirit of TMTOWTDI,
perhaps there wants to be a way to treat a naming authority as defining
a "language" of sorts, so perhaps we could allow the naming authority
out front as if it were specifying the language:

    use JRANDOM:Num;
    use JRANDOM:Num-1.3;

which would be short for

    use Num-*-JRANDOM;
    use Num-1.3-JRANDOM;

Then we'd write our "done_by" role above as:

    role Num-1.3-JRANDOM does STD:Num does Complex;
    method re (--> STD:Num) { self }
    method im (--> STD:Num) { 0.0 }

and there's no visually disturbing * there--though of course it's still
there semantically.  Probably we need to say that once a compilation
unit looks up a library name and resolves the version and authority,
it should stay resolved to that same long name for the rest of the
compilation.  That is, STD:Num becomes an alias to Num-6.0.2-STD or
whatever for the rest of the compilation.  Or at least the rest of
the lexical scope...not sure how I feel about two classes in the
same compilation unit getting a different version of Num, but it
could happen if we limit the alias to the lexical scope and each is
of the form

    class Foo {
        does JRANDOM:Num;
    class Bar {
        does JRANDOM:Num;

so maybe such aliases are hoisted to the outermost lexical scope or
some such, so they latch on for the whole compilation unit at least.
Alternately, we put some kind of transactional lock on the library
so it can't appear to change state in the middle of compilation.
That might be the wiser course.


Reply via email to