-
-
Notifications
You must be signed in to change notification settings - Fork 741
Fix splitter!pred and splitter(string) #1502
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
Conversation
Just about the best thing I've read all day! |
static if (fullSlicing) | ||
return _input[0 .. _end]; | ||
else | ||
return _input.take(_end); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be _end - 1
to match the full slicing behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are n
elements in [0 .. n]
, so ... not really. Ideally, I could just use return _input.take(_end);
for all code paths, as take knows how to slice... except for strings. Also, I need to change that code to return _input.save.takeExactly(_end);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, forget I said anything, I misread the code.
Don't get your hopes up too high yet, I just marked one function as deprecated, so its not fully fixed until it is removed. |
if (_next.empty) | ||
{ | ||
_input = _next; | ||
_end = _end.max; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OT: I know you didn't introduce this, but I don't like the usage of .max
on a variable of a non-UDT. size_t.max
or typeof(_end).max
could work, but just .max
really confused me here (since .max
is really the property of the type and not the variable).
Anyway you can leave it in, no big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, sure, I'll fix it. No problem.
All points addressed. |
@monarchdodra Can you please add some tests which specifically verify that Other than that, I think that this is ready to merge. I think that these changes are sorely needed as |
Nice, I was able to catch that there is actually no I also found an existing little discrepancy though, when splitting an empty range: import std.stdio, std.algorithm;
void main()
{
int[] input;
writefln("%s: %s", `splitter(input, 0)`, splitter(input, 0));
writefln("%s: %s", `splitter(input, [0])`, splitter(input, [0]));
writefln("%s: %s", `splitter!"a == 0"(input)`, splitter!"a == 0"(input));
} Produces:
This seems wrong to me. I don't think splitting an empty range with an element should create any tokens at all. In particular, while I could accept a difference in beahvior between elem/range splitting, I do not accept a difference with elem/pred. The buggy behavior is in split elem, right? I'll see if I can easily fix it here, but if not, I'll leave it as is, and deal with it later (I was planning to make some fixup changes to the other splitter in another pull). |
@monarchdodra Splitting on an empty range should definitely result in an empty range. I actually had to switch to using |
@jmdavis : Fixed. Good for final review. |
//@@@6730@@@ This exists already in std.array, so this declaration, at best, will only create ambiguity. | ||
//unfortunatly, an alias will conflict with the existing splitter in std.algorithm. | ||
//It needs to be removed. | ||
deprecated("std.algorithm.splitter(string) is deprecated in favor of std.algortihm.splitter(string)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a quick nitpick. You misspelled "algorithm" in the message (you also misspelled "unfortunately" in the comment, but the deprecation message actually matters, since that'll end up in the deprecation warning). Also, this says that you're deprecating std.algorithm.splitter in favor of... itself. So, presumably, the misspelled algorithm is actually supposed to be array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strange, I remember fixing that already...
Fix splitter!pred and splitter(string)
This seems to have caused https://d.puremagic.com/issues/show_bug.cgi?id=11701. What's the problem with just leaving a forwarding function in std.algorithm? |
it's ambiguous. The idea is to remove the deprecated function asap, and the problem will spontaneously solve. |
I'll give a thoroughly detailed explanation and motivation about this tomorrow. Sleep time :) |
This fixes:
(links:)
as well as "unlocks"
splitter!pred
for forward ranges. Also fixes the splitting behavior ofsplitter!pred
, which was just wrong, which, in turn, also fixesstd.array.splitter
.FWI, this is a toned down failed pull I had oppened 9 months ago: #934.
This fix can be review in 3 parts
1: A complet
splitter!pred
rewriteI did this because
splitter!pred
was completely inconsistent with the rest of the splitter functions:leadingtrailing delimiters where omittedThe new implementation has the exact same behavior as the other splitters. Also, the new implementation works on forward ranges. The new implementation is arguably simpler, even though it handles more types.
2: This leads to a
std.array.splitter(string)
rewrite:std.array.split
has a string specific overload that takes no teminator: This special case takes a string, and splits it on unicode white, and returns no empty tokens. Unfortunatly,std.array.splitter(string)
was simplyreturn std.algorithm.splitter!(std.uni.isWhite)
. This means thatsplit
andsplitter
did not have the same output. Un-acceptable. Now it does.3: Deprecate
std.algorithm.splitter(string)
This string function specific function has no reason to be in algorithm. The only thing it is doing, is creating ambiguity for users who have both algorithm and string included.
(4: Also included:
std.array.split!pred
, which was missing for some stringe reason)