-
-
Notifications
You must be signed in to change notification settings - Fork 610
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
allow default valued parameters after template variadics #7831
Conversation
|
Thanks for your pull request, @timotheecour! We are looking forward to reviewing it, and you should be hearing from a maintainer soon. Some tips to help speed things up:
Bear in mind that large or tricky changes may require multiple rounds of review and revision. Please see CONTRIBUTING.md for more information. Bugzilla references
|
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.
Huge fan of this and I'm impressed that's a two line change.
People have been complaining about this on the NG forever and it was cited as one of the reason why logging in D "sucks".
Also
- You can add at least https://issues.dlang.org/show_bug.cgi?id=8687 to the fixed bugs.
- This needs a PR to dlang.org to update the spec
CC @MartinNowak as he mentioned this on Bugzilla:
While working on limited lifetimes (@safe RC/Uniq) I ran into another use-case where a default argument is needed.
| */ | ||
|
|
||
| import std.typecons : tuple; | ||
| import std.conv : text; |
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 import Phobos if not absolutely required and you have a strong motivation.
- It makes the testsuite a lot slower to run (DMD has to parse entire Phobos for every test)
- If this ever fails, it makes it a lot harder to debug into
Thus, there are many "implementations" of tuple in the testsuite (do a grep) - here's a simple one:
struct Tuple(T...){
T expand;
alias expand this;
}
auto tuple(T...)(T t){ return Tuple!T(t); }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.
done; we definitely should add that to CONTRIBUTING.md
also, maybe a linter that would show this kind of policy violation
src/dmd/dtemplate.d
Outdated
| */ | ||
| size_t rem = 0; | ||
| for (size_t j = parami + 1; j < nfparams; j++) | ||
| { | ||
| Parameter p = Parameter.getNth(fparameters, j); | ||
| if(p.defaultArg) |
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.
Style
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.
done
|
What happens with code like this, will it compile? string foo(T...)(T a, string file = __FILE__) if (T.length == 1)
{
return null;
}
foo(1, "bar"); |
|
@jacob-carlborg I added a test. it does not compile as expected (and doesn't get confused by the fact "bar" is of same type as "file"). |
19273c5 to
b0e1538
Compare
|
PTAL, all comments addressed.
done
will do after this is merged (or do you recommend another way?) EDIT: see dlang/dlang.org#2169 |
|
Yay! Thank you, @timotheecour for doing this. |
|
Just seen it in the changelog, thx.
Could be helpful would have been the better wording, mainly to pass a default allocator as last argument and keep tracking it's scopeness. |
|
This PR changed the behavior of valid code. Even though default parameters didn't make sense (because you had to specify them), it didn't stop actual code from using them. See issue 19057. I think the better fix would be to make default parameters actually work (and match the parameters if the trailing arguments have the same type). In other words: void foo(A...)(A a, int x = 1, int y = 2)
{
writeln(a, x, y);
}
void main()
{
foo("hello"); // 1
foo("hello", 5); // 2
foo("hello", 5, 6); // 3
}Prior to this PR, 1 and 2 were errors, but 3 worked and printed "hello56" My expectation is that it should print "hello12", "hello52", "hello56". I don't get why parameters with default values should never match the actual arguments. |
That would be a disaster in the making for |
No, it wouldn't. You just wouldn't do that, until we can figure out a better way (see issue 18919). Just go back to the templated versions for now.
It's pretty obvious to me, to cut down on complexity and template bloat. What's easier/more understandable? void foo(A...)(A args, int timeout)
// or
void foo(A...)(A args) if (A.length > 0 && is(A[$-1] == int))
{
int timeout = a[$-1];
}It's not for us to question how people have written their code. |
Function parameters with default values are now allowed after variadic template parameters, and always take their default values. This allows using special tokens (eg FILE) after variadic parameters, which was previously impossible.
Eg:
This should be preferred to the previous workaround, which caused template bloat: