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