From S06:
sub bar ($a,$b,$c,:$mice) { say $mice }
sub foo (\$args) { say $args.perl; &bar.call($args); }
The C<.call> method of C<Code> objects accepts a single C<Capture>
object, and calls it without introducing a C<CALLER> frame.
And from S12:
In addition to C<next METHOD>, the special function C<call> dispatches
to the next candidate, possibly with a new argument list:
call; # calls with the original arguments
call(); # calls with no arguments
call(1,2,3); # calls with a different set of arguments
And back in S06:
The entire argument list may be captured by the C<\$args> parameter.
It can then be passed to C<call> as C<[,] =$args>:
# Double the return value for &thermo
&thermo.wrap( -> \$args { call([,] =$args) * 2 } );
The inconsistency between these three things called "call" is vexing to
me. One is a method and takes a capture and only a capture. The second is
a special function and takes an argument list, but also has a special
arglistless form that passes on the original arguments. The third is a
function that takes only a function list, but apparently lacks a
arglistless form (otherwise, why bother with capturing an arglist in the
example?).
I believe the current spec works. I just think the inconsistency is
bad--the three things called "call" do very similar things, but take
completely different arguments. I suspect this is just historical smear
and we just need to back up and normalize.
(Let me quickly note here that I don't think it's possible to write a
subroutine or method that can take either a bare argument list or a
Capture and treat them the same, because of the intractable ambiguity that
would arise in the case of an argument list that actually contains a
single capture as its only positional element. If I'm mistaken, then
other avenues open up. But I don't think I am.)
Audrey confirmed to me on IRC that the motivation for the arglistless form
was that passing on the original arguments will likely be one of the most
common uses of call. And I certainly can't argue with that, I agree.
But why, then, does .call not have an argumentless form? (Because we
can't write user-defined methods, short of C<is parsed> tricks, that
differentiate between .meth and .meth()? We can't write user-defined subs
that do that either, AFAIK...)
Might I propose the following normalization:
1. .call, method definition call(), and .wrap call all take captures.
2. .call() and both types of call() all pass on the arguments of the
current subroutine.
3. To call with no arguments, use .call(\()) and call(\()).
4. Introduce some syntax for getting a capture of the current argument
list explicitly. Perhaps $?ARGS or $?_ or $?CAPTURE. One shouldn't
have to choose between repeating your 20 parameters in order to take a
capture of them, and eliminating your nice self-documenting 20
parameter names so you can use the easy \$arglist trick.
Trey