On 7/17/05, Yuval Kogman <[EMAIL PROTECTED]> wrote:
> I have another view.
> 
> The Num role and the Str role both consume the Eq role. When your
> class tries to both be a Num and a Str, == conflicts.
> 
> I have two scenarios:
> 
>         class Moose does Num does Str { ... }
> 
>         # Moose was populated with:
>         multi method infix:<==> (Moose does Num, Moose does Num) { ... }
>         multi method infix:<==> (Moose does Str, Moose does Str) { ... }

Which is an ambiguity error.

> OR
> 
>         # Str and Num try to add the same short name, and a class
>         # composition error happenns at compile time.

Which is a composition error.  So they both amount to the same thing.

> Recently I discussed MMD with chromatic, and he mentioned two things
> that were very important, in my opinin:
> 
>         * The Liskov substitution principal sort of means that MMD
>           between two competing superclasses, no matter how far, is
>           equal

Amen.  For those of you who have not been exposed to this "paradox",
here's an example:

    class A      {...}
    class B is A {...}
    class C is B {...}
    class D is A {...}
    
    multi foo(C $x, A $y) { "(1)" }
    multi foo(A $x, D $y) { "(2)" }

If you call foo(C.new, D.new), (1) will be called (because it has
distance 1, while (2) has distance 2).  Now suppose I refactor to
prepare for later changes, and add two *empty* classes:

    class A      {...}
    class B is A {...}
    class C is B {...}
    class E is A { }
    class F is E { }
    class D is F {...}

Now if you call foo(C.new, D.new), (2) will be called instead of (1)
(because (1) has distance 3, while (2) still has distance 2).  That is
how Liskov subtly breaks.  As a matter of taste, classes that don't do
anything shouldn't do anything!  But here they do.  If I had only put
E in and omitted F, we would have moved from a functioning program to
a breaking one.

>         * Coercion of parameters and a class's willingness to coerce
>           into something is a better metric of distance

Well, if you think metrics at all are a good way to do dispatch.

> Under these rules the way this would be disambiguated is one of:
> 
>         - Moose provided it's own infix:<==>
>         - Moose said which <==> it prefers, Num or Str. A syntax:
> 
>                 multi method infix:<==> from Str;
> 
>           (this could also be used for importing just part of a
>           hierarchy?)

Well, I like your proposal.  It's a very generics-oriented world view,
which I hold very dear.  However, you didn't actually solve anything. 
What happened to our numeric == and string eq.  Are you proposing that
we toss out string eq and let MMD do the work?

If I recall correctly the reason for == and eq existing and being
distinct is so that you don't have to do:

    [EMAIL PROTECTED]()+$expression] == +%another{long($hairy % expression()) }
    ^..................................^

You can't see what's going on according to that operator, because the
eye scanning distance is too great.  We still need to satisfy the
scripters who like the distinction between numeric and string
comparison.  It's hard for me to argue for them, since I'm not one of
them.

One more possibility is operator adverbs.  We could assume that == is
generic unless you give it a :num or :str adverb:

    $a == $b       # generic
    $a == $b :num  # numeric
    $a == $b :str  # string

But that has the eye scanning distance problem again.  Maybe that's a
flaw in the design of adverbs this time...

Luke

Reply via email to