Skip to content

Commit 6713a41

Browse files
committed
Update Compile-Time Argument Lists article
Add headings. Mention .tupleof.
1 parent 55f935e commit 6713a41

File tree

1 file changed

+48
-21
lines changed

1 file changed

+48
-21
lines changed

articles/ctarguments.dd

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,29 @@ $(D_S Compile-time Argument Lists,
44

55
$(HEADERNAV_TOC)
66

7-
$(P Compile-time lists is an important metaprogramming concept that comes naturally
7+
$(H2 $(LNAME2 Background, Background))
8+
9+
$(P Compile-time lists are an important metaprogramming concept that comes naturally
810
from D support for $(LINK2 variadic-function-templates.html, variadic templates). They
9-
allow a programmer to operate on types, symbols and expressions enabling the ability to define
11+
allow a programmer to operate on types, symbols and expressions, enabling the ability to define
1012
compile-time algorithms that operate on types, symbols and expressions.
1113
)
1214

13-
$(P For historical reasons those sometimes can be called tuples in documentation or compiler
14-
internals but don't get confused : this doesn't have much in common with tuples that
15+
$(P $(B Note:) For historical reasons these lists can sometimes be called tuples in documentation or compiler
16+
internals, but don't get confused - they don't have much in common with tuples that
1517
commonly exist in other languages. Sequences of values of different types that can be
16-
returned from functions are provided by $(LINK2 phobos/std_typecons.html#.Tuple, std.typecons.Tuple).
18+
returned from functions are provided by $(PHOBOS typecons, .Tuple, std.typecons.Tuple).
1719
Using term "tuple" to mean compile-time lists is discouraged to avoid confusion, and if encountered
1820
should result in a $(LINK2 https://issues.dlang.org, documentation bug report).
1921
)
2022

21-
$(P Consider this simple snippet:)
23+
$(P Consider this simple variadic template:)
2224

2325
---
2426
template Variadic(T...) { /* ... */ }
2527
---
2628

27-
$(P `T` here is variadic $(LINK2 spec/template.html#TemplateArgumentList, template argument list)
29+
$(P `T` here is a $(DDSUBLINK spec/template, variadic-templates, TemplateParameterSequence),
2830
which is a core language feature. It has its own special semantics,
2931
and, from the programmer's point of view, is most similar to an array of compile-time entities - types,
3032
symbols (names) and expressions (values). One can check the length of this list
@@ -39,15 +41,17 @@ $(HEADERNAV_TOC)
3941
pragma(msg, T[1]);
4042
}
4143

42-
alias Dummy = Variadic!(int, 42);
44+
alias dummy = Variadic!(int, 42);
4345
// prints during compilation:
4446
// int
4547
// 42
4648
---
4749

48-
$(P However, the language itself does not provide any means to define such lists outside of
50+
$(H2 $(LNAME2 AliasSeq, AliasSeq))
51+
52+
$(P The language itself does not provide any means to define such lists outside of
4953
a template parameter declaration. Instead, there is a
50-
$(MREF_ALTTEXT simple utility, std, meta) provided by the D standard
54+
$(MREF_ALTTEXT simple utility, std, meta) provided by the standard
5155
library:
5256
)
5357

@@ -63,10 +67,10 @@ $(HEADERNAV_TOC)
6367
import std.meta;
6468
// can alias to some other name
6569
alias Name = AliasSeq!(int, 42);
66-
pragma(msg, Name[0]);
67-
pragma(msg, Name[1]);
70+
pragma(msg, Name[0]); // int
71+
pragma(msg, Name[1]); // 42
6872
// or work with a list directly
69-
pragma(msg, AliasSeq!("aaa", 0, double)[2]);
73+
pragma(msg, AliasSeq!("aaa", 0, double)[2]); // double
7074
---
7175

7276
$(H2 $(LNAME2 available-operations, Available operations))
@@ -137,6 +141,9 @@ $(H2 $(LNAME2 available-operations, Available operations))
137141
*/
138142
---
139143

144+
$(P $(B Note:) $(DDSUBLINK version, staticforeach, Static foreach)
145+
should be preferred in new code.)
146+
140147
$(H2 $(LNAME2 auto-expansion, Auto-expansion))
141148

142149
$(P One less obvious property of compile-time argument lists is that when used
@@ -163,11 +170,13 @@ $(H2 $(LNAME2 auto-expansion, Auto-expansion))
163170

164171
$(H2 $(LNAME2 homogenous-lists, Homogenous lists))
165172

166-
$(P An `AliasSeq` that consist of only type or expression (value) elements are
173+
$(P An $(ALOCAL AliasSeq, AliasSeq) that consists of only type or expression (value) elements are
167174
commonly called "type lists" or "expression lists" respectively. The concept of
168175
a "symbol list" is rarely mentioned explicitly but fits the same pattern.
169176
)
170177

178+
$(H3 $(LNAME2 type-seq, Type lists))
179+
171180
$(P It is possible to use homogenous type lists in declarations:)
172181

173182
---
@@ -176,6 +185,8 @@ $(H2 $(LNAME2 homogenous-lists, Homogenous lists))
176185
void foo(Params); // void foo(int, double, string);
177186
---
178187

188+
$(H4 $(LNAME2 type-seq-instantiation, Type list instantiation))
189+
179190
$(P D supports a special variable declaration syntax where a type list acts as a type:)
180191

181192
---
@@ -188,33 +199,49 @@ $(H2 $(LNAME2 homogenous-lists, Homogenous lists))
188199
variables[1] = 42.0;
189200
variables[2] = "just a normal variable";
190201
}
191-
192-
/* The compiler will rewrite such a declaration to something like this:
193-
202+
---
203+
$(P The compiler will rewrite such a declaration to something like this:)
204+
---
194205
int __var1;
195206
double __var2;
196207
string __var3;
197208
alias variables = AliasSeq!(__var1, __var2, __var3);
198-
*/
199209
---
200210

201-
$(P This is also what happens when declaring a variadic template function:)
211+
$(P So a type list instance acts as a symbol list that only aliases
212+
variables.)
213+
214+
$(P $(DDSUBLINK spec/template, variadic-templates, Variadic template functions)
215+
use a type list instance for a function parameter:)
202216

203217
---
204218
void foo(T...)(T args)
205219
{
206-
// 'args' here is a compile-time list of symbols that
207-
// refer to underlying compiler-generated arguments
220+
// 'T' is a type list of argument types.
221+
// 'args' is an instance of T whose elements are the function parameters
222+
static assert(is(typeof(args) == T));
223+
args[0] = T[0].init;
208224
}
209225
---
210226

227+
$(P $(B Note:) $(PHOBOS typecons, .Tuple, std.typecons.Tuple) wraps a type list instance,
228+
preventing auto-expansion, and allowing it to be returned from functions.)
229+
230+
$(H3 $(LNAME2 value-seq, Expression lists))
231+
211232
$(P It is possible to use expression lists with values of the same type to declare array literals:)
212233

213234
---
214235
import std.meta;
215236
static assert ([ AliasSeq!(1, 2, 3) ] == [ 1, 2, 3 ]);
216237
---
217238

239+
$(H4 $(LNAME2 tupleof, Aggregate field lists))
240+
241+
$(P $(DDSUBLINK spec/class, class_properties, `.tupleof`) is a
242+
class/struct instance property that provides an expression list
243+
of fields.)
244+
218245
)
219246

220247
Macros:

0 commit comments

Comments
 (0)