-
-
Notifications
You must be signed in to change notification settings - Fork 744
Add Unary Overload of startsWith() and endsWith() #3752
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
1931832
to
8b3f9bb
Compare
Is there any difference between this and |
Not sure about front vs. opIndex, but it may matter for length vs. empty. I forget whether there's ever a case where empty does non-trivial work, but if such a case exists, then maybe we should use length if possible. |
The motivation for this is purely usability or perhaps discoverability for new users and ease of remembering a solution when the other overloads have been learnt. |
Honestly, I seriously question that this is worth adding. All it's doing is creating a function that does
That's trivial to write yourself, and this overload goes against the idea that
but if it's that simple, I think that it's pretty pointless to add it to Phobos. |
f7c6099
to
c1a0363
Compare
Simplified implementations. |
Implementation seems OK. Not sure if something this simple is worth adding to Phobos, though. I'll let the other Phobos devs decide. |
I don't think it's worth it, but I'm alright if we decide to add it for completeness' sake. |
These are worth adding; the counterargument doesn't quite stand - by it, However, please consolidate the docs with I preapprove and archive this. If you need further resolution please email me. Thanks! |
@andralex do you mean that I should extend the main documentation for |
@nordlow That would make the most sense, I think. Add |
*/ | ||
bool endsWith(alias pred = "a", R)(R doesThisEnd) | ||
if (isInputRange!R && | ||
is(typeof(unaryFun!pred(doesThisEnd.front)) : bool)) |
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.
This constraint is not enough, as I found out the hard way recently. This code won't compile although it should, because among
returns a uint
which for some reason does not implicitly cast to bool.
//Error: cannot deduce type...
"asdf".startsWith!(c => c.among!('a', 'b', 'c'));
It'd probably be better to change it to:
if (isInputRange!R && __traits(compiles, cast(bool)unaryFun!pred(doesThisStart.front)))
Or something similar.
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.
Is this problem different from the binary case? If so, how? If not, isn't it better to tackle this problem in a another PR addressing all the overloads of startsWith
and endsWith
?
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.
What is the "binary case"?
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.
Sorry, I meant the case when pred
is a binaryFun
. if we should fix the constraints for these two new overloads we might aswell fix the constraints for all the other overloads aswell, right? Your proposed new constraint works for me, anyhow.
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.
It's probably a good idea, though I don't know if changing the constraints for the other overloads would break any code. Regardless, I think your implementation of isIfTestable
from the other PR would fit here.
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.
Ok, I'll look into it.
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.
I don't think this is the right PR for that. It's a wider Phobos issue that I think should be tackled separately.
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.
Don't overcomplicate things. Here you don't need bool, just ifTestable. I recall we have it somewhere from a recent pull request.
Well, where Actually, with regards to the multiple arguments, I think that |
Should the return type of the unary overload be If |
It should return |
I think the decision block tag can be removed; people may not review this because of that tag. |
I guess if this comes in we should add a corresponding overload for |
@jmdavis, it wouldn't solve the problem in general. The issue is that many of these algorithms check if the return type of the predicate function is implicitly convertible to |
c1a0363
to
0e91a82
Compare
FYI: |
Except that the results aren't always used in if statements. It might make more sense to not require that the result be implicitly convertible to |
The documentation for these new overloads still needs to be merged with the existing overloads as Andrei requested. There should be one non-ditto ddoc comment for |
It's an unrelated function. Please create separate PR for it. |
These overloads should be How do we make this happen considering that See also: http://forum.dlang.org/post/gincfsrbdypejnrdjjlx@forum.dlang.org |
@nordlow: There is no way to express "this function does not throw if empty() is false" in the type system, so this can't be done in general. |
What about adding a wrapper function to Phobos, say It seems http://dlang.org/phobos/std_exception.html#.assumeWontThrow could be used right? |
As long as And as for ranges of characters, they can pretty much never involve |
@nordlow asked me by email, there are any number of conditions that we can easily prove during compilations they won't throw but it's outside type system's capability to carry the proof. I'd say just use |
@andralex Then I must be missing something here, because the only way that these functions should be And in all of the examples in the unit tests, they can't be |
@jmdavis oh I see what you're saying. Various components of the expression may throw for other reasons than using D's type system cannot detect that kind of stuff. So just give up on trying to make the function |
We often use |
As long as
In general,
IMHO, we should just make it so that |
It's not that simple. |
Well, then I'm missing something here. Certainly, if
can't be inferred as
because while a programmer can see whether it can throw or not by verifying that the format specifiers work with the given arguments, that's something that can only be programmatically determined at runtime. In contrast, if Regardless, if the compiler fails to infer |
Sorry, I misunderstood - thought you want the compiler to figure the conditional, i.e. for many ranges if they're not empty the front won't throw. |
$(D bool) if the first element in range $(D doesThisEnd) fulfils predicate | ||
$(D pred), $(D false) otherwise. | ||
*/ | ||
bool endsWith(alias pred = "a", R)(R doesThisEnd) |
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's no need for a default predicate here. r.endsWith
is weird at best.
OK @nordlow so it seems this is ready to go pending a few trivial work items. Could you please finish? Thx! |
Yeah. That couldn't be
Yeah. The main thing that still needs to be fixed here based on the previous comments is that the ddoc comments for the existing overloads should be updated to encompass these new overloads rather than having separate documentation for them. If that had been done after the last update back in November, then I probably would have merged it then. |
Ok, @andralex. I'm right on it. What happens with assumeWontThrow(!doesThisStart.empty && unaryFun!pred(doesThisStart.front)) when |
0e91a82
to
0a5cc5f
Compare
It'll throw an
And since per the range API, it's effectively undefined behavior for a range to have Please remove the |
0a5cc5f
to
f7f4847
Compare
@jmdavis ok. Removed calls to I guess such optimizations, if any, should be part of the compiler. Should be ready now. |
The compiler should infer
will never be inferred to be AFAIK, the compiler already does all of the attribute inference for this code that it's supposed to be able to do, though it's certainly possible that there are bugs related to attribute inference that I'm not aware of (particularly if it related to lambdas or some other language construct that might require attribute inference on the predicate). |
Auto-merge toggled on |
Add Unary Overload of startsWith() and endsWith()
Adds overload that enables calling
startsWith
andendsWith
with only ahaystack
and predicatepred
.See discussion at: http://forum.dlang.org/post/zobvqdmxnjnilqibtcph@forum.dlang.org
Should
RandomAccess
have special treatment via.length
andopIndex
or should we just use.empty
and.front
for every case?If not I guess we could just do
right?