On Fri, Dec 19, 2003 at 12:24:29PM -0700, Luke Palmer wrote:
: Abhijit A. Mahabal writes:
: > On Fri, 19 Dec 2003, Larry Wall wrote:
: > 
: > > On Fri, Dec 19, 2003 at 10:23:45AM -0800, Austin Hastings wrote:
: > > : Of course, when I do:
: > > :
: > > :   my $x = 0 but (true|false);
: > > :
: > > : then what happens?
: > >
: > > That's the problem with making them methods.  Any such operational
: > > definition is going to get you in trouble.  I think I like them better
: > > as enums, because then you can have junctions of them functioning as
: > > a kind of subtype.
: > 
: > Is that thought about just traits, or also about roles? 
: 
: Neither.  It's just about roles.  We're having another vocabulary
: conflict; refer to the vocabulary doc.

I've been trying to capitalize Traits when I'm referring back the Traits
paper, and keeping it lowercase when I mean Perl 6 compile-time traits.
Sometimes it means I have to recast the sentence not to say "traits"
at the beginning though...

: > Sometime earlier Larry mentioned that roles could add multimethods,
: > and my worry about that is this:
: >     If you simultaneously have a multi method with a signature and
: > another without, given a particular call to this multimethod how do you
: > choose which of the two happens if the signature matches? 
: 
: Probably the same way you disambiguate when normal multimethods abound.
: The more specific signature wins, if it matches.

A crude distance calculation is done in typespace for all the involved
parameters.  It is sufficiently crude that ties can arise when we *ought*
to be uncertain which method to call.  In that case we'll have some
way of declaring how to break the tie.  If the tie can't be broken,
and exception is then thrown.

: Though I do see how this might introduce subtle bugs.  I'm a big fan of
: method name-only equivalence, so I would argue that it overrides (or
: subsides if it isn't being slathered on), but then I don't have
: experience with large-scale projects.

These multis are intra-class multis.  Outside the class, the method has
only a single name.  With ordinary method dispatch, you figure out which
name in which class you're going to call, and only then do you notice
that there are more than one of them within the class.  These are
"multi methods", not "multimethods" in the classic sense.  For classic
multimethods you have to declare multiple instances of "multi sub *foo"
and call it/them as a subroutine (or operator).  But we've generalized
"multi" to work in any namespace that would ordinarily reject a duplicate
definition.

: > Disallowing such clashes seems problematic because it may mean that if
: > the class writer used types and signatures these get forced onto the
: > user of the class.

Not necessarily.  Remember that multi dispatch is based on run-time
types, not declared types.  A module could be totally ignorant of
the run-time types of its values and it would still work, as long as
whatever produced the values in the first place labelled them with
the right type.  And you have to call the right constructor in the
first place to get the right values, even if you subsequently store
everything in typeless variables, so nothing is really forced on the
user that wasn't implicitly there to begin with.

: Everybody's going to be using signatures, though!  (Types are a
: different story)  Yeah, the typeless one would win, I think, unless the
: type happens to be Any.

Not sure what you mean.  The typeless one is likely to "lose" in the
sense that it's probably the furthest away in type space.  But by the
same token, it's likely to be the one that should be default in case of
ties, unless one of the tied entrants is specially marked as "better".
But it's hard to know how much tie-breaking information you want to
throw into the declarations, since you generally want to call the
most specific entrant that will successfully handle the arguments, and
"most specific" is a function of type distance, not which entrant yells
the loudest about its own superiority.  So maybe the better solution
is to allow class derivations to specify their type distance if it's
other than 1, just as IP routing tables can have a notion of which
hops are expensive and which ones are cheap.  It's probably better
to attach such information to the class rather than splattering it
all over multi-dom.  As with IP routing, mostly it's the "expensive"
routes that are specifically marked, and everything else defaults to 1.
A derivation that redefines most of the base class's methods should
probably be marked as an "expensive route".  (Such derivation distance
could be automatically calculated, but then our mechanism is never
crude enough to get ties when we probably should.)

Larry

Reply via email to