On Thu, Oct 27, 2005 at 22:19:16 -0400, Stevan Little wrote:
> Hello all,
> 
> I have a question about method conflict resolution works for roles,  and I 
> cannot seem to find this in any 
> of the Apoc/Syn documents.
> 
> Here is the basic issue:
> 
> role Foo {
>      method foo { ... }
>      method bar { ... }  # we will use this later :)
> }
> 
> role Bar {
>      method foo { ... }
> }
> 
> role FooBar {
>      does Foo;
>      does Bar;
> }
> 
> Now, at this point we have a method conflict in suspension since  (according 
> to A/S-12) method conflicts do 
> not throw an error until a  role is composed into a class. This means that 
> when I do this:
> 
> class MyClass does FooBar {}
> 
> an exception is thrown. Unless of course MyClass has a &foo method,  which 
> will disambiguate the conflict. 
> My question then is, can FooBar  (the role) disambiguate the &foo conflict?

IMHO yes, but it doesn't have too. It should be able to leave it to
the class to decide.

> role FooBar {
>      does Foo;
>      does Bar;
>      method foo { ... }
> }
> 
> Now, on the surface this seems obvious, of course the FooBar role  should be 
> able to disambiguate. However, 
> when we expand the example  other issues show up.
> 
> role Baz {
>      does Foo;
> }
> 
> class MyClass2 does FooBar does Baz {}  # Will this die?

<splice>

> But thats not all, we have a potential problem with &foo again. Baz  will 
> provide &foo from Foo, but FooBar 
> will provide it's own &foo  (which we used to disambiguate). So our 
> disambiguation is not  ambiguated 
> again.

</splice>

yes, since the methods are coming from different context, and they
may have different meanings. While FooBar::foo resolves the conflict
from the assimilation of Foo::foo and Bar::foo, it does it only
within FooBar.

If, OTOH we have a diamond inheritence:

        role A { method foo { ... } }
        role B does A {};
        role C does A {};
        class D does A does B { };

I'm not sure we need to resolve the conflict.

> Now, since MyClass2 actually does Foo twice, does that mean &bar  creates a 
> conflcit? Since &bar would be 
> found through FooBar and Baz.  I would think the answer here would be no, and 
> that we would build  some 
> kind of unique list of roles so as to avoid repeated consumption  like this.

No conflict - an assimilated role is identicle to itself even
through different paths since it doesn't get access to private or
protected member data of it's consuming roles.

If, on the other hand, we have

        role X trusts Foo does Foo {
                has $:foo;
        }

        role Y trusts Foo does Foo {
                has $:foo;
        }

        role Foo {
                method foo {
                        $:foo++;
                }
        }

        class C does X does Y { }

there is a conflict, because Foo is reaching into either X's private
member $:foo or Y's private member $:foo (btw, they should never
conflict with each other).

The moment a method will have behavior that is different in two
different role consumptions it will be conflicting, but this will
only happen to a method from the same class if it has some private
symbols resolved at role composition time using class friendship.


I think it is ambiguous, s

> A (deceptively) simple solution to this is that MyClass2 needs to  
> disambiguate. But this means that our 
> roles are not really black  boxes anymore. In order to properly disambiguate 
> this we need to know  where 
> all the &foo methods are coming from (Foo, Bar and FooBar), and  potentially 
> what is inside these &foo 
> methods (especially in the case  of FooBar since it is attempting to 
> disambiguate, it's behavior could  be 
> very specific). It probably would also become important to know  what other 
> methods &foo interacts with 
> since we potentially have 3  different expected versions of &foo.

        method foo is Foo::foo;

or

        method foo (*$a) { ./Foo::foo(*$a) }

or

        &foo ::= &Foo::foo;

> In the end, we will have probably looked inside every method defined  in Foo, 
> Bar, FooBar and Baz in order 
> to properly write MyClass2.  IMHO, this is sort of defeating the usefulness 
> of roles at this point.

I disagree - you have to know what a role is actually giving you to
exploit it. Too much black boxing makes your programming language
seem like a Kafka story.

> So what do you all think??

Role method conflicts should only be dealt with if the user knows
what the roles are actually doing anyway. This will probably be
familiar code, and if not it warrants familiarity.

I don't think we can let the user use library code without being
aware of the library code internals at all. Abstraction that works
like this is usually either crippled or useless. 90% of the time you
don't want to know, but there are exceptions.

-- 
 ()  Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418  perl hacker &
 /\  kung foo master: /me sushi-spin-kicks : neeyah!!!!!!!!!!!!!!!!!!!!

Attachment: pgpmmr3g6z6ZK.pgp
Description: PGP signature

Reply via email to