www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 23665] New: Add traits

https://issues.dlang.org/show_bug.cgi?id=23665

          Issue ID: 23665
           Summary: Add traits
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: qs.il.paperinik gmail.com

Add `__traits` to expose information about a template’s parameters: A template
parameter has the following properties:

1. An identifier.
2. A kind: It is a value parameter, a type parameter, an alias parameter, or a
sequence parameter. Arguably, a template `this` parameter is a type parameter,
but IMO, it should be its own kind.
3. A type if it is a value parameter. (Alias and sequence parameters can be
bound to value arguments that have types, but the parameter itself has no
type.)
4. Optionally a constraint.
5. Optionally a default.

Chellanges:
1. Only values have types.
2. Types, constraints, and defaults might not be accessible, a symbolic (not a
string) return is useful.
3. Types, constraints, and defaults can be dependent on previous paramters; a
symbolic return is not possible in that case.


Proposed specification:

First, provide the trait `templateParameterLength` taking an alias to a
template that returns the number of (lexical) template parameters. (By lexical,
I mean that a sequence parameter counts as exactly 1 parameter, even if
logically, it is “0 or many”.)

Note: For the following that take an index, if the index is out of range (≥
`templateParameterLength`), it is a compile error. The wording assumes that the
index is in range.

For each template parameter property, provide a trait named
`templateParameter(Identifier|Kind|Type|Constraint|Default)`, respectively,
taking an alias to a template and an index that returns compile-time
information of the respective properties (if available – a parameter might not
have a type, constraint, or default).
E.g. `__traits(templateParameterKind, std.meta.AliasSeq, 0)` returns the kind
of the only parameter: sequence.

Also provide the trait `templateParameterHas(Type|Constraint|Default)` taking
an alias to a template and an index that returns a bool providing information
about the availability of that property:
`templateParameterHasType` is a compile-error when the parameter is not of kind
value. (The programmer should use `static if` to enusre the parameter queried
is of kind value.) It returns `true` if the type is independent of previous
template parameters and `false` if it is dependent on them. (This might be a
best-effort, i.e. there could be edge cases in which `false` could be returned
when `true` is actually possible.)
`templateParameterHas(Constraint|Default)` returns returns `true` if the
template parameter has a constraint or default, respectively.

Identifiers are returned as strings (cf. `__traits(identifier)`). Unnamed
parameters are syntactically not possible, the string is never empty or `null`.

The kind could be designated by a finite set of strings ("value", "type",
"alias", "sequence", and "this") or by values of an `enum`.

`__traits(templateParameterType)` returns a sequence consisting of 1 or 2
entries: The first entry is the string used to define the parameter; the second
entry is present and an alias to the type when
`__traits(templateParameterHasType)` is `true` (and thus the type is
well-defined).

For constraints and defaults, `__traits(templateParameter(Constraint|Default))`
compiles if `__traits(templateParameterHas(Constraint|Default))` is `true`.
Because constraints and defaults can depend on previous parameters, they cannot
always be extracted symbolically. Again, a sequence consisting of 1 or 2
entries is returned: The first entry is the string consisting of the tokens
making up the constraint/default, the second is present if the
constraint/default is independent of previous parameters and thus can be
extracted symbolically.

--
Feb 02 2023