Larry Wall wrote:
> Jonathan Lang wrote:
> : Larry Wall wrote:
> : > Jonathan Lang wrote:

> Also, there will be access to the list of call candidates for SUPER::
> (and presumably ROLE::) such that the class's method can get explicit
> control of which super/role method or methods get called.  So we can
> have methods that fail-over to the next candidate.  It's just not the
> default way to resolve multiple methods with the same signature.

Make micromanaging possible, but not mandatory.  Sounds good to me.  

> : > Another possibility is that the class's method could be declared to 
> : > be the default multi method in case the type information is not 
> : > sufficient to decide which role's multi method should be called.  
> : > Maybe if it's declared "multi" it works that way.  Otherwise it's 
> : > just called first automatically.  
> : 
> : ...meaning that the question of "which role do you mean?" has already
> : been addressed by the time the ROLE:: "deference" gets used.  
> 
> No, in this case the ROLE:: deference has already given up on finding
> a unique role to call, and called the class's method to break the tie,
> or do something really generic, or call more than one of the role
> methods, or die.  

Oh; OK.  

> : Although I'm not following what you're saying here in terms of the
> : third means of disambiguation.  Could someone provide an example, 
> : please?  
> 
>     role Pet {
>       method feed (PetFood $x) {...}
>     }
>     role Predator {
>       method feed (PredatorFood $x) {...}
>     }
>     class DangerousPet does Pet does Predator {
>     }
> 
> If DangerousPet doesn't define a feed method at all, then we might 
> dispatch to Pet and Predator as if their methods had an implicit 
> "multi".  

And the C<default> trait is the tie-breaker when several options are
equally likely candidates (in terms of type information); OK.  

So what happens if more than one of the candidates is tagged as the
default?  The same thing as if none of them was?  This could happen if
both Predator and Pet have declared their 'feed' methods as the default.  

> Arguably, the role's might be required to declare their methods "multi"
> if they want to participate in this, but that's one of those things
> that feel like they ought to be declared by the user rather than the
> definer.  On the other hand, maybe a role would feel that its method
> *must* be unique, and leaving out the "multi" is the way to do that.
> But I hate to get into the trap of culturally requiring every method
> in every role to specify "multi".  It's a little too much like the C++
> ubiquitous-const problem.

What about making multi dispatches the assumed behavior, with a C<unique>
keyword to explicitly shut it off (for the sake of optimization)?  That
is, replace the C<multi> keyword used to define routines that participate
in multiple dispatching with a C<unique> keyword used to define routines
that don't.  

> My hope for unifying traits and superclasses is that, if you call an
> ordinary class using "is", the wicked thing that it does is insert
> itself into the "ISA" property of the class.  

When you say "is foo", you're inheriting if foo is a class and you're
adding a trait if foo is a trait.  OK.  This would also imply that the
proper way to access a trait's namespace would be identical to the
explicit means of accessing a superclass's namespace.  

> Where that may cause problems if you want to inherit from an existing 
> trait that does something else wicked.  But then, traits aren't often 
> going to be inherited anyway, since their purpose is to break the 
> rules.  

Unless you're trying to create a variation on an existing trait, of
course.  

> We can maybe inherit from classof(trait) to get around any difficulties.

Perhaps you could use C<type> instead of C<classof>?  More concise and
just as meaningful.  

> So I'm still thinking we do inheritance with "is" rather than "isa".
> We just have to keep our names straight.  Generally, traits will
> be lowercase, and true class or role names start with an uppercase
> letter.

But then, this remains merely a convention; a sloppy programmer (or one
who isn't worried about his code being extensible) could violate it
without the compiler complaining.  

The only fear that I have here is whether we're violating the "different
things should look different" principle: are traits and superclasses
similar enough to each other to be added to a class by the same means?  It
might not be a bad idea to include "isa" as a more explicit alternative to
"is", with the added benefit that "isa traitname" would be short for "is
classof(traitname)".  It also occurs to me that traits can be thought of
as adjectives (thus the "is <trait>" vs. "is a <class>" distinction) -
another way to attach an adjective to a noun in English is to prepend it
to the noun: 

  my Dog $Spot is red; 
  my black Cat $Tom; 
  my thoughtful $Larry is overworked; 

where red, black, thoughtful, and overworked are traits.  

Or is this too much?  

In a similar vein, what about making a disjunction of classes in an C<is>
or C<isa> clause synonymous with a sequence of appropriate clauses?  Ditto
with traits and C<is>, roles and C<does>, attributes and C<has>, etc.;
thus: 

  class DangerousPet does Pet & Predator {
  }

would be the same as

  class DangerousPet does Pet does Predator {
  }

> I've come around to thinking that C<but> always applies a new subclass
> (possibly cached).  That new subclass can just compose a single role,
> but it could compose several roles and add new methods of its own to 
> control the multiple roles.  See my other message today on this list for
> more speculation.
> 
> So the precedence rules are still invariant--a role supercedes
> inherited methods but is superceded by class methods.  We're just
> changing what C<but> means.  It now implies inheritance from the
> original class, since inheritance is the correct way to override.

Oh, that's good.  I like that.  

> : I was under the impression that the writers of the "Traits" paper that
> : you referred us to disliked "mixins" largely because they _did_ use an
> : order-of-precedence conflict resolution scheme; surely their concerns 
> : would apply equally well to what we're calling traits?  
> 
> Our traits are for cheating.  They're direct hooks into implementational
> details, encapsulated only by their name.  All well-behaved definitions
> should be using roles and classes instead.  The goal is not to avoid
> ordering dependencies entirely (which is impossible), but to avoid them
> when they're unnecessary.

Got it.  

=====
Jonathan "Dataweaver" Lang

__________________________________
Do you Yahoo!?
New Yahoo! Photos - easier uploading and sharing.
http://photos.yahoo.com/

Reply via email to