On Fri, 18 Sep 2015 00:51:42 -0700, larry wrote:
> 00:13 < TimToady> m: for (1,2,3).pairs X (4,5,6).pairs -> ($x,$y) { say "$x
> $y" }
> 00:13 <+camelia> rakudo-moar c0e0c9: OUTPUT«This type cannot unbox to a
> native string␤  in block <unit> at /tmp/YnA_LhZbRO:1␤␤»

It gives a nicer error message now:

    ➜  for (1,2,3).pairs X (4,5,6).pairs -> ($x,$y) { say "$x $y" };
    Too few positionals passed to ''; expected 2 arguments but got 0 in 
sub-signature
      in block <unit> at -e line 1

The reason for the error is that sub-signatures use `.Capture`, and 
`List.Capture` turns Pair elements into named arguments:

    ➜  dd (a => 1, 42, b => 2).Capture;
    \(42, :a(1), :b(2))

I too have got bitten by this trap before - it essentially makes it unsafe to 
pass lists containing Pair objects to code (think e.g. a third-party module) 
that expects arbitrary lists of objects, unless you can ensure that the code 
doesn't and never will end up binding the list to a sub-signature (or otherwise 
calling `.Capture` on it).

It's IMO also conceptually dubious. A List firmly represents the concept of 
"list of positional elements", and I see no compelling conceptual reason why 
`.Capture` should second-guess this meaning based on the *type* of the list 
elements.

So I can only assume that it works like it does now, for practical reasons - 
i.e. because something in core relies, or used to rely, on it working this way. 
But what?

Note that flattening things into argument lists *doesn't* suffer from this 
issue, because instead of `.Capture` it uses `.FLATTENABLE_LIST` + 
`.FLATTENABLE_HASH` which always cleanly treat list elements as positionals and 
hash entries as nameds.

Marking this ticket as [@LARRY].

Reply via email to