Comment #0 by default_357-line — 2022-10-17T10:37:48Z
Consider the following code:
import std;
void main() {
auto range = [1, 2].uniq!"true";
auto left = range.map!"[a]".joiner.array;
auto right = range.map!"[a]".array.joiner.array;
writefln!"left = %s, right = %s"(left, right);
assert(left == right);
}
left = [2], right = [1]
[email protected](8): Assertion failure
Something about the order in which joiner queries uniq makes uniq return a different "unique" element. While this is *technically* valid behavior as specified, it is very unexpected.
Comment #1 by default_357-line — 2022-10-17T10:52:54Z
Update: The actual issue is that uniq backwards iteration contains different elements than its forwards iteration:
import std;
void main() {
auto range = [1, 2].uniq!"true";
writefln!"forward %s, backward %s"(range.retro.array.retro.array, range.array);
assert(range.retro.array.retro.array == range.array);
}
I understand why uniq would want to work that way, but it should arguably not be allowed to: https://dlang.org/library/std/range/primitives/is_bidirectional_range.html says that `back` has to return "the last element in the range". It's undefined what exactly this means, but it's certainly questionable that "back" is an element that doesn't appear in the forward iteration order at all.
Comment #2 by dlang-bot — 2022-10-17T12:58:43Z
@FeepingCreature created dlang/phobos pull request #8610 "Fix issue 23422: Disable uniq backwards iteration if a predicate is passed." fixing this issue:
- Fix issue 23422: Disable uniq backwards iteration if a predicate is passed.
https://github.com/dlang/phobos/pull/8610
Comment #3 by robert.schadek — 2024-12-01T16:40:38Z