-
-
Notifications
You must be signed in to change notification settings - Fork 706
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
Add std.functional.bind #8376
Add std.functional.bind #8376
Conversation
|
Thanks for your pull request and interest in making D better, @pbackus! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + phobos#8376" |
|
Thanks!
To summarize a lot of it, I'm hesitant about such an addition to Phobos because I can't see many use cases outside tuples, and it is so broad that it allows doing e.g.: struct Coordinate { float longitude, latitude; }
Coordinate c;
...
c.bind!((latitude, longitude) => /* OOPS */);Note that the JavaScript equivalent behaves correctly: let c = {longitude: 12, latitude: 34};
(({latitude, longitude}) => /* OK */)(c);I think we actually can make the D construct behave like the JavaScript one if we wanted to, which is why maybe that should be a separate discussion from #8372. |
|
Here's a non- int[string] cityPopulations = [
"New York" : 8_804_190,
"Los Angeles" : 3_898_747,
"Chicago" : 2_746_388,
"Philadelphia" : 1_603_797,
"Seattle" : 737_015,
"Boston" : 675_647
];
// Print names of cities with populations > 1mil and < 5mil
cityPopulations.byKeyValue
.filter!(bind!((name, pop) => pop > 1_000_000 && pop < 5_000_000))
.map!(bind!((name, pop) => name))
.each!writeln;
|
There is |
Sadly I don't think this is possible in library code without resorting to string mixins, but I'd be delighted to be proven wrong about that. |
| { | ||
| assert(toCtString!0 == "0"); | ||
| assert(toCtString!123456 == "123456"); | ||
| } |
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.
Why not static asserts instead?
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 is copy+pasted from std.sumtype, and it uses runtime assert there too.
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.
Can't this be in a shared module? I don't see the reason for a runtime assert.
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.
Once this is merged I plan to submit a separate refactoring PR addressing these issues. Since this PR introduces a new feature, I want to keep refactoring out of it.
|
@atilaneves Thanks! Though, I'd love a rationale of your choice. |
It's more general, and I didn't see why constrain it to tuples. |
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 still needs a changelog entry.
It's discussed in the other pull request and #8376 (comment). (Not sure if you didn't see the discussion or if you found it unconvincing.) Edit: Well, I won't say no to a more generic version if the BDFL says the concerns are not worth worrying about 😄 Thanks @pbackus for the nice implementation! |
I saw and read it, yes, I was more convinced by the other arguments. I hope that makes sense! |
| } | ||
|
|
||
| /** | ||
| * Passes the fields of a struct as arguments to a function. |
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 find it confusing that only struct fields are mentioned here. tuples should be mentioned too
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.
Do you mean language tuples (like in AliasSeq) or std.typecons tuples? The latter are just structs.
For language tuples you can just use the Identity template.
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 was referring to std.typecons.tuples.
| import core.lifetime : move; | ||
|
|
||
| // Forwards the i'th member of `args` | ||
| // Needed because core.lifetime.forward doesn't work on struct members |
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.
Maybe we can fix core.lifetime.forward.
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.
Not possible, unfortunately—forward takes its argument as an alias template parameter, and so does not have access to the this pointer at runtime.
Fixes Issue 22736 - Add destructuring bind for std.typecons.Tuple tuples
|
@RazvanN7 Added a changelog entry. |
Fixes Issue 22736 - Add destructuring bind for std.typecons.Tuple tuples
This version works for all
structtypes, not juststd.typecons.Tuple. See #8372 for discussion.