Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are callwith and samewith supposed to do?

Tags:

raku

What are callwith and samewith supposed to do? I thought callwith was supposed to run a subroutine of the same name of the current subroutine, but using the arguments I pass to it.

From the docs:

callwith calls the next matching candidate with arguments provided by users and returns that candidate's return value.

To me it sounds like inside the two-arity MAIN subroutine (i.e. MAIN($a,$b)) that callwith($x) would call MAIN($x).

But it doesn't:

multi MAIN ($a, $b) {
    my $result = callwith("$a$b");
    say "Got $result from MAIN(\$a)";
}

multi MAIN ($x)    {
    say "Hello $x";
    return True;
}
$ perl6 callwith.p6 foo bar
Use of uninitialized value $result of type Any in string context.
Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful.
  in sub MAIN at callwith.p6 line 3
Got  from MAIN($a)

Then this definition of samewith makes it sound like calling samewith($x) from inside of the two-arity MAIN (i.g. MAIN($a, $b)) would try to call the two-arity MAIN again ("current candidate", right?).

samewith calls current candidate again with arguments provided by users and returns return value of the new instance of current candidate.

But it actually calls the one-arity MAIN:

multi MAIN ($a, $b) {
    my $result = samewith("$a$b");
    say "Got $result from MAIN(\$a)";
}

multi MAIN ($x) {
    say "Hello $x";
    return True;
}
$ perl6 samewith.p6 foo bar
Hello foobar
Got True from MAIN($a)

So am I seeing correct behavior by callwith and samewith? If so, what am I misunderstanding? I'll gladly update the documentation once I understand this issue better.

I'm using Rakudo-Star-2018.01 on CentOS 7.4.1708.

like image 596
Christopher Bottoms Avatar asked Apr 06 '18 18:04

Christopher Bottoms


1 Answers

The behavior you are seeing is correct.

From But here's my dispatch, so callwith Maybe by Zoffix:

samewith — make the same call from scratch, following a new dispatch chain, with these new arguments, and come back

Zoffix also mentioned that if using one of the next____ or call_____ functions (e.g. nextwith or callwith), any previously rejected candidates will not be reconsidered.

So, it sounds like the signature* (or capture) is already fixed before using callwith. samewith gets around this because it "redispatches" "from scratch" (Thanks Brad Gilbert for your comments, and Zoffix for your blog).

If you need to change the signature used (or capture), use samewith or just use the subroutine name again (MAIN in this case).

*I originally called this "arity", but "signature" or "capture" are better terms (thanks @jjmerelo and @Tinmarino for pointing me to these terms).

like image 182
Christopher Bottoms Avatar answered Nov 18 '22 10:11

Christopher Bottoms