On Sat, Sep 25, 2021 at 2:30 PM Joseph Brenner <doom...@gmail.com> wrote:

> > Since subsets are just code it would be difficult to impossible
> > to determine all of the ones that can match without actually
> > running them all. This would slow down every call that uses
> > multiple subsets.
>
> I can see how there would be a big performance hit, but I haven't
> yet turned up any reference to this behavior in the docs.  I
> don't see anything to clue you in that subsets are an exception,
> and I don't think there's anything about
> order-of-definition-of-sub being a tie-breaker under any
> circumstances.
>

The docs are not the definitive source of truth.
They are at best an approximation.

> By most narrow candidate, it means by type.
>
> If you'd said that to me, I'd still have expected it to work the
> way that I did, because the way I look at it I'm creating new
> types via subset.
>

By type I mean something that can be instantiated or subclassed.
Subsets cannot do either of those two things.
You can create a subset of a subset, but that is not the same thing.


> > All subsets "of" the same type are sorted by the order they are
> > written.
>
> Even if I'd figured that two subsets of Str were going to treated as Str,
> I'd have expected an "Ambiguous call" error.
>
> If the two subsets are defined in different modules I suspect you
> could get some strange behavior that would be hard to debug.
> It's not always immediately obvious in what order two things were
> defined.
>

Doing what you want would make using subsets with multis much less useful.

    multi factorial ( 0 --> 1 ){}
    multi factorial ( 1 --> 1 ){}
    multi factorial ( UInt \n ){ factorial(n - 1) * n }

    say factorial( 1 );
    # ERROR: both UInt and 1 subsets match.

You could modify the general case, but that is tedious and error prone.

    multi factorial ( Int \n where {$_ >= 0 && $_ != 0 && $_ != 1} ){
factorial(n - 1) * n }

(The reason I didn't just do $_ >= 2 is that if another multi is added it
should be dealt with in the same way as 0 and 1)


> On 9/24/21, Brad Gilbert <b2gi...@gmail.com> wrote:
> > This is intended behavior.
> >
> > Since subsets are just code it would be difficult to impossible to
> > determine all of the ones that can match without actually running them
> all.
> > This would slow down every call that uses multiple subsets.
> >
> > By most narrow candidate, it means by type. All subsets "of" the same
> type
> > are sorted by the order they are written.
> >
> > The ambiguity it talks about is when two candidates have the same level
> of
> > type for a given input. For example Str and Int for an IntStr.
> >
> >
> > On Fri, Sep 24, 2021, 1:32 AM Joseph Brenner <doom...@gmail.com> wrote:
> >
> >> This code uses multi dispatch with constraints that are ambiguous
> >> in a few cases, because there's some overlap in the lists of
> >> monsters and heroes: 'mothera' and 'godzilla'.
> >>
> >>     my @monsters = < godzilla  mothera     ghidora  gammera  golem
> >> wormface >;
> >>     my @heroes   = < beowulf   bluebeetle  bernie   mothera  godzilla
> >> maynard_g_krebs >;
> >>
> >>     subset Monster of Str where { $_ eq any( @monsters ) };
> >>     subset Hero    of Str where { $_ eq any( @heroes ) };
> >>
> >>     ## Monster is favored over Hero because of the order of definition
> >> of these multi subs
> >>     multi sub speak (Monster $m) {
> >>         say "The monster, $m roars!";
> >>     }
> >>     multi sub speak (Hero $h) {
> >>         say "The hero, $h shouts!";
> >>     }
> >>
> >>     speak('ghidora');  # The monster, ghidora roars!
> >>     speak('beowulf');  # The hero, beowulf shouts!
> >>     speak('mothera');  # The monster, mothera roars!
> >>
> >> I would've expected that in the case of 'mothera', this would
> >> error out unless an "is default" was added to one of the multi
> >> subs.  Instead the ambiguity is resolved by the order of
> >> definition: if you reverse the order of the "multi sub speak"s,
> >> then mothera is treated as Hero not Monster.
> >>
> >> This is not the behavior described in the documentation:
> >>
> >>      https://docs.raku.org/language/glossary#index-entry-Multi-Dispatch
> >>      Multi-dispatch§
> >>
> >>      The process of picking a candidate for calling of a set of
> >>      methods or subs that come by the same name but with different
> >>      arguments. The most narrow candidate wins. In case of an
> >>      ambiguity, a routine with is default trait will be chosen if
> >>      one exists, otherwise an exception is thrown.
> >>
> >
>

Reply via email to