skipOver should have a single argument with pred version#5497
skipOver should have a single argument with pred version#5497JackStouffer wants to merge 1 commit intodlang:masterfrom
Conversation
…e argument with pred version
|
Thanks for your pull request, @JackStouffer! Bugzilla references
|
|
Hmm, I guess it is a bit weird that this will skip things in a loop. Meaning, If we decide to keep the inconsistency, then perhaps returning This function as it is certainly seems more useful, though. What do you think of naming it |
| * Returns: | ||
| * `true` if elements were skipped over, `false` otherwise. | ||
| */ | ||
| bool skipOver(alias pred, R)(ref R r) if (ifTestable!(typeof(r.front), unaryFun!pred)) |
There was a problem hiding this comment.
A) countUntil
import std.algorithm.iteration : filter;
import std.range;
return (&r).refRange.chain.countUntil!(x => !unaryFun!pred(x)) > 0;B) find
import std.range;
return (&r).refRange.enumerate.find!(x => !unaryFun!pred(x.value)).front.index > 0;There was a problem hiding this comment.
How do you mean that?
It was just an FYI on how this functionality currently can be achieved. Of course, both ways are a bit clunky and won't be as fast as this implementation.
There was a problem hiding this comment.
@andralex If we could get find to be partially instantiatable with just the predicate then that solves a bunch of problems at once, without introducing new symbols. Unfortunately actually doing it is tricky - see comments below.
There was a problem hiding this comment.
@CyberShadow I think making find instantiable with the predicate would help a lot of cases. That doesn't necesarily compete with skipOver which is useful for parsing.
Yes, I often use a combination of the "alternatives" I listed.
N.B.: There's a reason why I made this PR: #4985
tl;dr: no new symbols just for negation (unfortunately)
|
|
Argh! alias skipWhile(alias pred) = find!(not!(unaryFun!pred));I'd say that we fix |
I would use the opportunity to fix |
|
|
|
For this to work, |
|
That, or ignore the two-argument version of |
|
Here is a rough draft for a plan: // Old definitions
static if (false)
{
/// Two-argument
Haystack find(alias pred="a==b", Haystack, Needle)(Haystack h, Needle n)
{
return h;
}
/// One-argument
Haystack find(alias pred, Haystack)(Haystack h)
{
return h;
}
}
/// New definitions
static if (true)
{
/// Two-argument (no pred)
Haystack find(Haystack, Needle)(Haystack h, Needle n)
{
return h;
}
template find(alias pred)
{
/// Two-argument (with pred)
Haystack find(Haystack, Needle)(Haystack h, Needle n)
{
return h;
}
/// One-argument (with pred)
Haystack find(Haystack)(Haystack h)
{
return h;
}
}
/// Backwards compatibility for explicit
/// find!(pred, Haystack, Needle) instantiations
template find(alias pred, Haystack, Needle)
{
alias findPred = find!pred;
alias find = findPred!(Haystack, Needle);
}
/// Backwards compatibility for explicit
/// find!(pred, Haystack) instantiations
template find(alias pred, Haystack)
{
alias findPred = find!pred;
alias find = findPred!Haystack;
}
}
/////////////////////////////////////
unittest
{
// No pred
assert(find("a", "b") == "a");
// With pred
assert(find!"a==b"("a", "b") == "a");
assert(find!"a=='x'"("a") == "a");
// Explicit instantiations (optional backwards compat)
assert(find!("a==b", string, string)("a", "b") == "a");
assert(find!("a=='x'", string)("a") == "a");
// Partial instantiation (desired)
alias find1 = find!"a=='x'";
assert(find1("a") == "a");
alias find2 = find!"a==b";
assert(find2("a", "b") == "a");
}We'll just need to move the tests for the with-predicate two-argument overload together with the with-predicate one-argument overload. |
Sounds like you volunteered to do it yourself ;-) |
|
Argh. There's like 8 overloads! |
| * `true` if elements were skipped over, `false` otherwise. | ||
| */ | ||
| bool skipOver(alias pred, R)(ref R r) if (ifTestable!(typeof(r.front), unaryFun!pred)) | ||
| { |
There was a problem hiding this comment.
Stop creating AST nodes for something that's done automatically (i.e default initialization).
There was a problem hiding this comment.
That is bad advice.
I can't find a quote at the moment, but Walter has been always saying that default initialization is not meant to provide useful default values, but to make using un-initialized variables deterministic and, wherever possible, an error. When possible, the default value of a type is an invalid one (NaN for floating-point types and '\xFF' for chars, which is an invalid UTF-8 code unit); the reason why most other types are initialized to zero is that they do not have an "invalid" value.
So, do initialize your variables explicitly (when you feel it makes sense to) and do not rely on their default value.
There was a problem hiding this comment.
What you didn't know is that the author of the PR is also the person who suggested to add a D-Scanner check for default initialization. My review comment couldn't be more legit.
There was a problem hiding this comment.
Not relevant. The pull request is for Phobos, not some personal repository of Jack's.
| * r = the range to skip over | ||
| * Returns: | ||
| * `true` if elements were skipped over, `false` otherwise. | ||
| */ |
There was a problem hiding this comment.
Nice. Please add but use /// ditto for the documentation and consolidate with the existing doc.
|
Next time please add "Fix Issue $Number" so that the dlang bot can associate your PR with the bug fix. That way it can be found at a search through PRs. I couldn't find this PR so I opened another one with almost the same fix, as it can be seen above. I think that this PR (or mine) should be merged and if consensus is reached with find, then we can modify skipOver. My implementation avoids extra initializations and assignments by using a do while. I suggest you take a look before merging this. |
|
@andralex What do you think of fixing |
andralex
left a comment
There was a problem hiding this comment.
The other implementation is more efficient and uses ///ditto. Shall we close this?
| * Returns: | ||
| * `true` if elements were skipped over, `false` otherwise. | ||
| */ | ||
| bool skipOver(alias pred, R)(ref R r) if (ifTestable!(typeof(r.front), unaryFun!pred)) |
There was a problem hiding this comment.
@CyberShadow I think making find instantiable with the predicate would help a lot of cases. That doesn't necesarily compete with skipOver which is useful for parsing.
Agreed, but actually doing so without breaking code seems tricky (though still possible). I was hoping you might have some insights.
Oops, right, I was thinking of |
Yeah we first need to reduce them to be able to go ahead. |
Ping @CyberShadow