Captures are sensitive things, they can only be used "as-is" inside a
scalar, otherwise you have to enforce a context and it is no longer a
capture, but one of the views of its content.

for instance...

  sub foo {
    return @thingy, :named($value);
  sub bar($capture) {
    my $named := |$capture;
    my @things := |$capture;

The problem with the above code, is that the :($capture) signature,
already enforces item context, and therefore the two statements in sub
bar will simply fail.

That being said, I'd like to suggest a new syntax:

  sub bar(\$capture) {

This syntax will mean that you want that positional argument without
forcing any context. This is something different from

  sub bar(|$capture) {

which takes the entire capture sent to that invocation and store in the
variable, the proposed syntax would allow:

  sub foo {
     return 1,2,3;
  sub bar(\$capture, $other) {
  bar(foo(), "somethingelse");

This need came out because of

  method postcircumfix:<( )>($capture)

we need to receive the positional argument for .() without forcing the
context. I understand this method used to have a (|$capture) signature,
and it was changed by a request I made, but I'd like to remember that (|
$capture) and (\$capture) are completely different things, and SMOP
already takes advantage on that, the current signature for .() in SMOP

  method postcircumfix:<( )>(\$capture, :$cc)

where $cc is there to support call with current contination (currently
used in exception handling).

The other method that requires such concept is

  method dispatch($object, $identifier, \$capture) {...}

in ClassHOW, which will actually call postcircumfix:<( )> in the end, so
it needs the capture "as-is".

Aditionally to this syntax, one point requires attention. If

 foo((a => 1));

makes the pair a positional argument, it's natural that


makes the capture a positional argument, instead of expanding it into
the argument list, and thus closing the loop in "how to use a capture
object" ;)


Reply via email to