On 1/22/21 12:55 AM, Jon Degenhardt wrote:
On Friday, 22 January 2021 at 05:51:38 UTC, Jon Degenhardt wrote:
On Thursday, 21 January 2021 at 22:43:37 UTC, Steven Schveighoffer wrote:
auto sp1 = "a|b|c".splitter('|');
writeln(sp1.back); // ok
auto sp2 = "a.b|c".splitter!(v => !isAlphaNum(v));
writeln(sp2.back); // error, not bidirectional
Why? is it an oversight, or is there a good reason for it?
I believe the reason is two-fold. First, splitter is lazy. Second, the
range splitting is defined in the forward direction, not the reverse
direction. A bidirectional range is only supported if it is guaranteed
that the splits will occur at the same points in the range when run in
either direction. That's why the single element delimiter is
supported. Its clearly the case for the predicate function in your
example. If that's known to be always true then perhaps it would make
sense to enhance splitter to generate bidirectional results in this case.
Note that the predicate might use a random number generator to pick the
split points. Even for same sequence of random numbers, the split points
would be different if run from the front than if run from the back.
I think this isn't a good explanation.
All forms of splitter accept a predicate (including the one which
supports a bi-directional result). Many other phobos algorithms that
accept a predicate provide bidirectional support. The splitter result is
also a forward range (which makes no sense in the context of random splits).
Finally, I'd suggest that even if you split based on a subrange that is
also bidirectional, it doesn't make sense that you couldn't split
backwards based on that. Common sense says a range split on substrings
is the same whether you split it forwards or backwards.
I can do this too (and in fact I will, because it works, even though
it's horrifically ugly):
auto sp3 = "a.b|c".splitter!((c, unused) => !isAlphaNum(c))('?');
writeln(sp3.back); // ok
Looking at the code, it looks like the first form of spltter uses a
different result struct than the other two (which have a common
implementation). It just needs cleanup.
-Steve