[RFC] Make std.algorithm.searching.skipOver an eponymous template to allow partial instantiation#5576
Conversation
|
Thanks for your pull request, @wilzbach! Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. |
| pred = The predicate that determines whether elements from each respective | ||
| range match. Defaults to equality $(D "a == b"). | ||
| */ | ||
| template skipOver(alias pred = "a == b") |
| isInputRange!R2) | ||
| { | ||
| if (r2.length > r1.length || r1[0 .. r2.length] != r2) | ||
| static if (is(typeof(pred) : string) && pred == "a == b" |
There was a problem hiding this comment.
I am aware that @andralex isn't a huge fan of this pattern, but without this, we can't have a default pred for skipOver and thus would need to duplicate all overloads (as previously done).
There was a problem hiding this comment.
If alternatives are a lot of aggravationm, then fine. But seeing template skipOver is already a sign that something has gotten too complicated...
There was a problem hiding this comment.
But seeing template skipOver is already a sign that something has gotten too complicated...
Making skipOver is fully on purpose and what this entire informal RFC PR is about.
|
I hate this pattern too. Can't we just add another template "overload" that only takes a predicate and then forwards to another version of |
How would this work without duplicating all function headers of |
|
Yeah, true. Looks like it can't be helped. |
Err, isn't this the by-the-book standard eponymous template pattern which allows partial instantiation and is already used in lots of places in Phobos, such as |
|
Btw another benefit of partial instantiation is that we get Dependency-Carrying Declarations a la DIP1005 for free :) template foo(alias pred = "a == b")
{
import std.range.primitives : isInputRange;
auto foo(R)(R r)
if (isInputRange!R)
{
import std.algorithm.iteration : sum;
return r.sum;
}
}
void main()
{
foo([1]); // <- remove this and no modules are imported
}Now without the use of the eponymous template: |
|
@andralex so what's your opinion on this? Can we move forward? |
|
So the current crop of bool skipOver(R1, R2)(ref R1 r1, R2 r2)
if (isForwardRange!R1
&& isInputRange!R2
&& is(typeof(r1.front == r2.front)));
bool skipOver(alias pred, R1, R2)(ref R1 r1, R2 r2)
if (isForwardRange!R1
&& isInputRange!R2
&& is(typeof(binaryFun!pred(r1.front, r2.front))));
bool skipOver(alias pred, R)(ref R r1)
if (isForwardRange!R
&& ifTestable!(typeof(r1.front), unaryFun!pred));
bool skipOver(R, E)(ref R r, E e)
if (isInputRange!R && is(typeof(r.front == e) : bool));
bool skipOver(alias pred, R, E)(ref R r, E e)
if (is(typeof(binaryFun!pred(r.front, e))) && isInputRange!R);My first notes independent on this PR:
Based on the above I'd say this PR may be worth it even if we discount for the advantages of partial instantiation and import. I'll now make a pass through the code looking for details. |
andralex
left a comment
There was a problem hiding this comment.
OK I'm fine with this. Before we open the floodgates to reworking everything this way, if this pattern is too frequent we may be better off with a small language addition (something like allowing overloading on template alias comes to mind).
| $(D r1) is left in its original position. | ||
| */ | ||
| bool skipOver(R1, R2)(ref R1 r1, R2 r2) | ||
| if (is(typeof(binaryFun!pred(r1.front, r2.front))) && |
There was a problem hiding this comment.
This should be ifTestable (not related to this PR but can go with it because code disobeying that doesn't compile anyway)
|
|
||
| /// Ditto | ||
| bool skipOver(R, E)(ref R r, E e) | ||
| if (is(typeof(binaryFun!pred(r.front, e))) && isInputRange!R) |
There was a problem hiding this comment.
predicate should be ifTestable
|
ping @wilzbach this is approved with a couple of nits, feel free to amend or commit as is |
Thanks for the ping and I am well aware of it, but I have been pretty busy with life for the last days :/ |
Okay I put this on the auto-merge queue now. |
|
I turned off automerge because it was turned on for 6 days and did not merge due to failure(s) in CyberShadow/DAutoTest |
|
ping @wilzbach |



From #5497 (comment)
It turns out that many functions in std.algorithm don't, so this is a RFC for evaluating the best way to move forward here. I picked the non-trivial function
skipOveras an example.