I agree that things like

   my @divisors = [X] @prime-factor-powers;
   
   my @transpose = [Z] @matrix;

look perfectly reasonable and elegant, and the fact that the single-sub-list 
edge-case ruins them is regrettable. Nor can I image any scenario where the 
current behavior of that edge-case is useful.

I assumed that because it was the natural result of a core Perl 6 design 
decision which is surely not under discussion anymore (the "single-argument 
rule" for list-munging routines like `zip` and `cross`), we would have to live 
with it.

But  Aleks-Daniel is right, it really would be great to find some way to "fix" 
this edge-case. Here's a first idea:

---

Maybe `reduce` could simply introspect the operator and if sees that the 
signature starts with a "single-argument slurpy" parameter (`+foo` / `+@foo`), 
adapt the calls to it accordingly?

At first glance that seems LTA (special cases are icky), but consider that:

1) `reduce` *already* introspects its operator and adapts its operation 
accordingly, in order to provide maximum DWIM regarding associativity, unity, 
etc.

2) The "single-argument rule" can be seen as just another calling convention. 
When we write `zip @foo`, the the parser may think a function is being called 
with one argument... but *we* know that we're sending all the sub-lists of @foo 
to be zipped, and that if we had wanted to send the single list @foo we would 
have had to write `zip (@foo,)` or `zip $@foo`.
`reduce` also knows that it wants to apply the operator to a single item in the 
edge-case in question, and it could adapts its call to make that happen for 
whatever calling convention the operator uses.

Point (2) raises the question if other built-ins like `map` and `grep` would 
have to learn about different calling conventions as well, for consistency.
But I don't think that's necessarily the case. Things like `map` are very 
generic in the sense that they don't understand anything about what is being 
piped through them... the user is fully in charge of controlling the inputs and 
outputs of the callback. (Also, the current behavior is actually useful there.)
`reduce` is more high-level, in the sense that it knows it's dealing with an 
operator and a list of elements to fold, and wants to call the operator with 
either zero, one or two of those elements at a time.

This shouldn't be interpreted as an RFC yet, just some thoughts. Someone would 
have to thoroughly think through the implications, and test the 
spectest/ecosystem fallout.

Reply via email to