Bug 9365 – Allow partially specified template aliases

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-01-21T12:50:45Z
Last change time
2024-12-13T18:03:50Z
Assigned to
No Owner
Creator
Peter Alexander
See also
http://see%20also%20http//d.puremagic.com/issues/show_bug.cgi?id=11403
Moved to GitHub: dmd#18515 →

Comments

Comment #0 by peter.alexander.au — 2013-01-21T12:50:45Z
It would be helpful if it were possible to alias partially specified templates. An example: void foo(A, B)() {} alias foo!int fooInt; Currently this fails with "Error: template instance foo!(int) foo!(int) does not match template declaration foo(A, B)()". However, if you write foo as: template foo(A) { void foo(B)() {} } Then it works. This would be useful because it would allow you to write things like: alias equalRoR = equal!equal; instead of having to write: alias equalRoR = binaryFun!((a, b) => equal!equal(a, b));
Comment #1 by andrej.mitrovich — 2013-01-21T13:15:33Z
This can be implemented in the library, the last thing you want is for templates being partially instantiated when you pass too few arguments instead of getting an error.
Comment #2 by peter.alexander.au — 2013-01-21T15:11:58Z
(In reply to comment #1) > This can be implemented in the library, the last thing you want is for > templates being partially instantiated when you pass too few arguments instead > of getting an error. There will be no partial instantiation (what it that anyway?) What I'm asking for is a rewrite from: alias A = B!(x, y); to alias A = ((args...) => B!(x, y)(args)); // if this was valid syntax when B has more than 2 non-default template parameters. The rest are determined using type deduction when A is invoked. This is frustrating: void foo(A, B)(A a, B b) {} foo(1, 2); // OK foo!(int)(1, 2); // OK foo!(int, int)(1, 2); // OK alias X = foo; // OK alias Y = foo!(int); // ERROR alias Z = foo!(int, int); // OK
Comment #3 by yebblies — 2013-01-21T20:19:02Z
Something like alias A(T) = B!(x, T); Is more likely and more flexible. Expanding to: template A(T) { alias A B!(x, T) }
Comment #4 by peter.alexander.au — 2013-06-09T23:35:09Z
(In reply to comment #3) > Something like > > alias A(T) = B!(x, T); > > Is more likely and more flexible. See my use case, with your suggestions, this wouldn't work: alias equalRoR = equal!equal; An alternative suggestion, is to change how function templates are expanded. Currently we have: void foo(A, B)(A a, B b) expanding to template foo(A, B) { void foo(A a, B b); } If instead, it expanded to: template foo(A) { template foo(B) { void foo(A a, B b); } } Then foo!int becomes a valid, alias-able symbol, which would solve the problem as well.
Comment #5 by monarchdodra — 2013-11-10T13:25:45Z
In reply to comment #3) > Something like > > alias A(T) = B!(x, T); > > Is more likely and more flexible. > > Expanding to: > > template A(T) > { > alias A B!(x, T) > } This is now a done functionality :)
Comment #6 by monarchdodra — 2013-11-10T13:31:00Z
In reply to comment #4) > (In reply to comment #3) > > Something like > > > > alias A(T) = B!(x, T); > > > > Is more likely and more flexible. > > See my use case, with your suggestions, this wouldn't work: > > alias equalRoR = equal!equal; > > An alternative suggestion, is to change how function templates are expanded. > Currently we have: > > void foo(A, B)(A a, B b) > > expanding to > > template foo(A, B) > { > void foo(A a, B b); > } > > If instead, it expanded to: > > template foo(A) > { > template foo(B) > { > void foo(A a, B b); > } > } > > Then foo!int becomes a valid, alias-able symbol, which would solve the problem > as well. I think this would also come with its own problems: For example, how would you tell apart full/partial, eg: void foo(U)(); void foo(U, V)(); alias F = foo!int; //which one is this? There's also some problems with constraints. It's difficult to do what you suggest if there is a constraint that depends on both A/B. At best, you can validate when the last parameter is specified.
Comment #7 by peter.alexander.au — 2013-11-10T13:58:24Z
(In reply to comment #6) > In reply to comment #4) > > (In reply to comment #3) > > > Something like > > > > > > alias A(T) = B!(x, T); > > > > > > Is more likely and more flexible. > > > > See my use case, with your suggestions, this wouldn't work: > > > > alias equalRoR = equal!equal; > > > > An alternative suggestion, is to change how function templates are expanded. > > Currently we have: > > > > void foo(A, B)(A a, B b) > > > > expanding to > > > > template foo(A, B) > > { > > void foo(A a, B b); > > } > > > > If instead, it expanded to: > > > > template foo(A) > > { > > template foo(B) > > { > > void foo(A a, B b); > > } > > } > > > > Then foo!int becomes a valid, alias-able symbol, which would solve the problem > > as well. > > I think this would also come with its own problems: > > For example, how would you tell apart full/partial, eg: > > void foo(U)(); > void foo(U, V)(); > > alias F = foo!int; //which one is this? This is no different than: alias F = foo; It matches the template, not the instantiation. See my rewrite suggestion. > There's also some problems with constraints. It's difficult to do what you > suggest if there is a constraint that depends on both A/B. At best, you can > validate when the last parameter is specified. It's the same as aliasing a template -- you validate only when it is used.
Comment #8 by jakobovrum — 2016-01-07T21:25:41Z
The below PR adds a library solution for this. https://github.com/D-Programming-Language/phobos/pull/3798
Comment #9 by robert.schadek — 2024-12-13T18:03:50Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18515 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB