Thank you Vadim, your explanation makes a lot of sense! On Tue, Jan 19, 2021 at 5:23 PM Vadim Belman <vr...@lflat.org> wrote:
> Hello, > > By "never returns" it's not meant that nextsame redispatches to the next > sub and skips the current stack frame. It only means that no statements > following nextsame will be executed. It's the same semantics as with > return. So, the best way to consider nextsame would be to think of it as of > 'return next-candidate(...)'. > > I would say that this is the semantics which cares about the caller. If > you put yourself in the shoes of your code user, imagine that you > introspect the multi in question with 'cando' which gives you the candidate > returning a List. It'd be very confusing to get an Int instead! > > Aside of this, the practice of returning so different values for rather > similar arguments doesn't look good for me. > > Best regards, > Vadim Belman > > On Jan 19, 2021, at 11:07 AM, Fernando Santagata < > nando.santag...@gmail.com> wrote: > > Hello, > I'm trying to understand how nextsame works. > > Apparently I started from the wrong assumptions: I thought that once the > first matched sub in the chain called nextsame, the arguments were matched > against the following subs regardless of the return value. > It seems that while the return value is not taken in account during the > match process, it is checked once the sub return its value and it generates > an error if the two candidates in the chain have different return types. > > The documentation ( > https://docs.raku.org/language/functions#index-entry-dispatch_nextsame) > reads: > > nextsame calls the next matching candidate with the same arguments that >> were used for the current candidate and never returns. >> > > and doesn't mention the return value. > > proto test(Str $a, |) {*} > multi test($a, Str $b --> List) { > nextsame if $b ~~ /\d+/; # if the second string contains a number > return $a, $b > } > multi test($a, Int() $b --> Int) { return $b } # coerces the second > argument to Int > > say test('hello', 1); # output: 1 > say test('hello', 'goodbye'); # output: (hello goodbye) > say test('hello', '1'); # error: Type check failed for return > value; expected List but got Int (1) > > Here I expected that in the third call, after the first multi matched, the > nextsame triggered a match on the second multi, regardless of the return > value. Instead apparently the match is triggered, but then the return value > of the first multi (List) is expected from the second multi (which returns > an Int). > > I don't know if this is the desired behavior; if so probably it deserves > to be documented. > > -- > Fernando Santagata > > > -- Fernando Santagata