Bug 24629 – Allow more than 1 set of template parameters

Status
NEW
Severity
enhancement
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2024-06-25T16:10:16Z
Last change time
2024-12-13T19:36:01Z
Assigned to
No Owner
Creator
Bolpat
Moved to GitHub: dmd#20475 →

Comments

Comment #0 by qs.il.paperinik — 2024-06-25T16:10:16Z
Apart from a `template` template, templates can be defined by giving the construct template parameters, e.g. `class C(T)`, `void f(T)(T x)`, `enum isConst(T) = …`, `alias Unshared(T) = …`, etc. Those are equivalent to a `template` template with the respective construct with the same name inside of it. Why only allow one level of nesting? There is no good reason not to allow for multiple nesting levels: ```d void f(T)(U)(T t, U u) { … } ``` would be lowered to: ```d template f(T) { template f(U) { void f(T t, U u) { … } } } ``` UFCS and IFTI work in a specific way with nested templates: Template arguments can be inferred for the innermost `template`. In the example, that would mean that callers _must_ provide `T` and the compiler can infer `U`. Example uses cases can be merging `opAssign` and `opOpAssign`: ```d struct S { alias opAssign = opOpAssign!""; template opOpAssign(string op) { auto opOpAssign(R)(R rhs) { … } } } ``` the latter could be: ```d auto opOpAssign(string op)(R)(R rhs) { … } ``` Note that in D, a set of template arguments can only contain one sequence argument. When more are needed, nested templates are necessary. I have encountered a case where 3 sets of template arguments would be useful: - The uppermost level is a customization point (one provides a boolean); the module exposes two aliases, one for the `true` and one for the `false` instance. Those are almost identical and implementing that twice makes no sense. - The next level is any number of lambdas - The innermost level takes the types of the arguments (which are usually inferred). Using that, instead of: ```d alias matchByType = matchByTypeImpl!false; alias matchByTypeExact = matchByTypeImpl!true; private template matchByTypeImpl(bool exact) { template matchByTypeImpl(fs...) { auto ref matchByTypeImpl(T)(auto ref T x) { … } } } ``` I could write: ```d alias matchByType = matchByTypeImpl!false; alias matchByTypeExact = matchByTypeImpl!true; private template matchByTypeImpl(bool exact)(fs...)(T)(auto ref T x) { … } ```
Comment #1 by robert.schadek — 2024-12-13T19:36:01Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20475 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB