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 
> <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

Reply via email to