-
-
Notifications
You must be signed in to change notification settings - Fork 745
find: return named tuples instead of anonymous #5962
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
|
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. |
9d1116b to
8d38cc7
Compare
quickfur
left a comment
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 like this. A lot. Anonymous tuples are hard to remember (is the haystack t[0] or t[1]?) and make user code more obtuse.
However, the named fields really really need to be described thoroughly in the ddoc header of each respective function. It's not good enough to just stick that into the return type.
(On that note, I'm a bit sad that the return type spec is getting long and scary to read... but that's an issue for another day, and out of scope for this PR. :-P)
|
I'm not sure about this. On one hand, it's technically a breaking change because named On the other hand, I doubt this type of code is very common. |
|
This is also more dubious that the linked PR because in that case the return type was Personally, I think the breakage will be at a minimum, but it will still exist. Paging @andralex for his opinion. |
|
First things first: I split this PR of into three parts:
Yep, but note that this is small subset - even comparison works: assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));
For
Done. Especially I like the improvement of the documentation for
Can't say more than this. I think in this case the gain outweighs the minimal cases where we might break code. |
8b7fb6f to
ccaead0
Compare
|
I'm tempted to say that |
|
|
||
| /** | ||
| Finds two or more $(D needles) into a $(D haystack). The predicate $(D | ||
| Finds two or more `needles` into a `haystack`. The predicate $(D |
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.
How about moving the changes of $(D...) to backticks to a different PR that we can merge immediately?
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.
Let's better follow-up on the various requests to use backticks in the docs and do it for std.algorithm once and for all?
-> #5970
For variadic overloads `std.algorithm.searching.find` will return a named tuple tuple instead of an anonymous tuple.
std/typecons.d(648): Error: reinterpreting cast from inout(string)* to inout(Tuple!(string, ulong))* is not supported in CTFE
std/algorithm/searching.d(2538): called from here: find(haystack, _param_1, _param_2)._Tuple_super()
std/typecons.d(977): called from here: canFind("dat", "pos", k)
std/algorithm/iteration.d(1148): called from here: __lambda1(front(this._input))
std/algorithm/iteration.d(1174): called from here: this.prime()
std/typecons.d(978): called from here: FilterResult(["dat"], false, null).empty()
std/typecons.d(978): while evaluating: static assert(FilterResult(["dat"], false, null).empty)
std/typecons.d(1021): Error: template instance std.typecons.Tuple!(float, "dat", ulong[2], "pos").Tuple.rename!(["dat":"height"]) error instantiating
std/typecons.d(1378): instantiated from here: Tuple!()
Don't they? This runs: void main(string[] args)
{
import std.typecons : Tuple;
alias Point = Tuple!(int, int);
alias PointNamed = Tuple!(int, "x", int, "y");
import std.traits : isImplicitlyConvertible;
static assert(isImplicitlyConvertible!(PointNamed, Point));
static assert(!isImplicitlyConvertible!(Point, PointNamed));
import std.stdio : writeln;
writeln(PointNamed.stringof, " is implicitly convertible to ", Point.stringof,
" but not vice versa.");
} |
|
Hmm... you're right, but now I don't understand why. Maybe it's because they're structs that have the same layout, so the compiler allows them to implicitly convert to each other...? |
|
ping @andralex This is a potentially breaking change, need your review & approval. |
|
I wish we just closed this. It created just work for everyone involved, and is liable to create more. |
|
Should we just close this then? |
Would you mind elaborating on this a bit? |
|
I don't deny it's nicer. But there's work in reviewing, work in fixing known breakages of existing code, and more future work on fixing other breakages. It doesn't seem on the right side of cost/reward. |
|
Gave this a fresh look, I can't shed the feeling "why are we bothering with low impact matter when there's so many big rocks to move". Anyhow, what are the cases that break - aside from those that explicitly check for exact |
@andralex I'm surprised at what the compiler allows; these are the cases I could think of OTOH: |
|
@MetaLang https://github.com/dlang/phobos/blob/master/std/typecons.d#L651 has a lot to do with this. Named tuples are subtypes of their unnamed counterparts. With this realization I think this PR is a go. Any breakage anyone sees? |
andralex
left a comment
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'm for this. If it causes major issues we didn't get all aspects of alias this right.
|
As discussed in this PR, changing Such a change should work as long as you ignore the issue of anyone who explicitly declared a |
|
Well, that discussion linked to one of the changes that had to be made to make Phobos compile when Based on the commit message, it seems to be a problem related to CTFE and casting. I did do some looking over Given that |
|
Got it, thanks. That's actually an easy fix - we need to use a non-names |
I dived a bit deeper and reduced the problem to this example: https://run.dlang.io/gist/9e497b0205031ee8370aa9fa1ea18399?compiler=dmd&args=-unittest%20-main%20-c However, I'm not sure how we can workaround this. If just the auto t1 = Tuple!(int, "x", string, "y")(1, "a");
void foo(Tuple!(int, string) t2) {}
foo(t1);So |
That's already the case today - even for named tuples the layout is as follows: struct Tuple
{
Types expand; // AliasSeq!(int, int)
} |
This runs into the same mentioned overload problems as just https://run.dlang.io/gist/9041fb8eac5134ffd47f0acbb2f4fb26?compiler=dmd&args=-unittest%20-main%20-c (updated link) |
|
@wilzbach link doesn't work but at any rate we can make it work. |
|
PR closed as stalled. If you wish to resurrect it you are welcome to do so. @tgehr This may be of interest to you. |
Motivation: Named tuples are a lot better to read.
There has been a precedent for this, see #5436