New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[X] @list-of-lists
misbehaves with list of one list
#6370
Comments
From @mschaThis is OK:
... but this is incorrect:
Expected output is: Note that [*] behaves as expected:
... since this is equivalent to:
|
From @AlexDanielI think this is related: Raku/doc#1400 On 2017-07-01 12:25:39, perl6@mscha.org wrote:
|
The RT System itself - Status changed from 'new' to 'open' |
From @mschaThat may indeed explain why it works the way it does, but that doesn't Let me explain how I found this bug.
|
From @AlexDanielI'd agree that it is a bug, yes. Well, the reason why it happens might be justified, but this is probably one of the fattest traps I've seen so far. I really think we should come up with a way to eliminate this trap somehow. Not sure how, but there must be a way and I really recommend anybody reading this to think in this direction (instead of writing a lot of text to come up with excuses to reject this ticket). Maybe it's something we can fix in v6.d, or maybe we can add some kind of warning right now. I don't know, but I truly hope that there is a solution. On 2017-07-01 13:17:58, perl6@mscha.org wrote:
|
From @smlsI agree that things like my @divisors = [X] @prime-factor-powers; 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`. 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. 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. |
From joshuamy@gmail.com
I don't think anything needs to be fixed. This is along the same vein as the misguided thinking that `[Z] (3,2)` should yield `(2,3)`. I also think the comparison to [*] is invalid since it operates on number-y things, and [X] explicitly operates on 2 or more lists or iterables. My thinking is that doing `[X] ((3,2),)` is kinda like doing `[X] ((3,2),Empty)`... Not exactly equivalent, but almost. The Cartesian product of singleton sets is again a singleton set (ie. product [[1]; [2]; [3]] is [1; 2; 3] My feeling is that current behavior is fine. At most, perhaps a warning in a similar vein to `sink context` warnings, eg. 'Useless use of meta-reduce [X] on single list' or something |
From @smlsOn Tue, 18 Jul 2017 07:45:16 -0700, joshuamy@gmail.com wrote:
Assuming I understand your analogy correctly, that's exactly what's *not* happening, and is why this RT exists. See: dd [X] 3, 2; # ((3, 2),).Seq The first two are unsurprising, but note how the third one is *also* being treated as the Cartesian product between the two sets `3` and `2`, rather than the single set `(3, 2)`. Also, scenarios where the argument list to `[X]` or `[Z]` is fixed-sized (like in these examples), isn't what is tripping people up (because there's no reason to write that in the single-sublist case anyway). The problem is with crossing or zipping a variable-sized list of lists, like in `my @transpose = [Z] @matrix;`, which works fine for most inputs but breaks down for the "@matrix has exactly one row" edge-case. I've explained why this is happening and why it ruins people's day in this docs ticket: [1], and this StackOverflow answer: [2]. [1] Raku/doc#1400 |
From @mschaIn my opinion, to decide whether it's a bug, you shouldn't look at the If someone states the current behaviour is correct, I'd like them to But perhaps an even easier way to look at it is: [X] (@a, @b, @c) is equivalent to @a X @b X @c and [X*] (@a, @b, @c) is equivalent to @a X* @b X* @c |
Migrated from rt.perl.org#131686 (status was 'open')
Searchable as RT131686$
The text was updated successfully, but these errors were encountered: