Skip to content

Commit 48da171

Browse files
authored
[spec/template-mixin] Improve docs (#3620)
* [spec/template-mixin] Improve docs Tweak wording. Add link to template instantiation scope. Move scope example up. Add subheadings. Move mixin virtual functions example to end. Move 'a mixin has its own scope' section up and add 'resolving ambiguities' subheading. * Link to template parameters, not just type parameters * Add link and mention overload sets
1 parent c32fef2 commit 48da171

File tree

1 file changed

+78
-69
lines changed

1 file changed

+78
-69
lines changed

spec/template-mixin.dd

Lines changed: 78 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ $(GNAME MixinQualifiedIdentifier):
2727
)
2828

2929
$(P A $(I TemplateMixin) can occur in declaration lists of modules,
30-
classes, structs, unions, and as a statement.
31-
The $(I MixinTemplateName) refers to a $(I TemplateDeclaration) or
30+
classes, structs, unions, or as a statement.
31+
$(I MixinTemplateName) must refer to a $(I TemplateDeclaration) or
3232
$(I TemplateMixinDeclaration).
33-
If the $(I TemplateDeclaration) has no parameters, the mixin
34-
form that has no !($(I TemplateArgumentList))
35-
can be used.
33+
If the $(I TemplateDeclaration) requires no parameters, $(I TemplateArguments)
34+
can be omitted.
3635
)
3736

38-
$(P Unlike a template instantiation, a template mixin's body is evaluated
37+
$(P Unlike a $(DDSUBLINK spec/template, instantiation_scope, template instantiation),
38+
a template mixin's body is evaluated
3939
within the scope where the mixin appears, not where the template declaration
4040
is defined. It is analogous to cutting and pasting the body of
4141
the template into the location of the mixin into a $(LINK2 #mixin_scope, nested scope). It is useful for injecting
@@ -44,6 +44,24 @@ $(GNAME MixinQualifiedIdentifier):
4444
template instantiations.
4545
)
4646

47+
$(SPEC_RUNNABLE_EXAMPLE_RUN
48+
------
49+
int y = 3;
50+
51+
mixin template Foo()
52+
{
53+
int abc() { return y; }
54+
}
55+
56+
void test()
57+
{
58+
int y = 8;
59+
mixin Foo; // local y is picked up, not global y
60+
assert(abc() == 8);
61+
}
62+
------
63+
)
64+
4765
$(SPEC_RUNNABLE_EXAMPLE_RUN
4866
------
4967
import std.stdio : writeln;
@@ -81,8 +99,11 @@ void main()
8199
}
82100
------
83101
)
102+
103+
$(H2 $(LNAME2 parameters, Mixin Parameters))
104+
84105
$(P Mixins can be
85-
$(DDSUBLINK spec/template, template_type_parameters, parameterized):)
106+
$(DDSUBLINK spec/template, parameters, parameterized):)
86107

87108
------
88109
mixin template Foo(T)
@@ -91,57 +112,6 @@ mixin template Foo(T)
91112
}
92113

93114
mixin Foo!(int); // create x of type int
94-
------
95-
96-
$(P Mixins can add virtual functions to a class:)
97-
98-
$(SPEC_RUNNABLE_EXAMPLE_RUN
99-
------
100-
import std.stdio : writeln;
101-
102-
mixin template Foo()
103-
{
104-
void func() { writeln("Foo.func()"); }
105-
}
106-
107-
class Bar
108-
{
109-
mixin Foo;
110-
}
111-
112-
class Code : Bar
113-
{
114-
override void func() { writeln("Code.func()"); }
115-
}
116-
117-
void main()
118-
{
119-
Bar b = new Bar();
120-
b.func(); // calls Foo.func()
121-
122-
b = new Code();
123-
b.func(); // calls Code.func()
124-
}
125-
------
126-
)
127-
128-
$(P Mixins are evaluated in the scope of where they appear, not the scope
129-
of the template declaration:)
130-
131-
------
132-
int y = 3;
133-
134-
mixin template Foo()
135-
{
136-
int abc() { return y; }
137-
}
138-
139-
void test()
140-
{
141-
int y = 8;
142-
mixin Foo; // local y is picked up, not global y
143-
assert(abc() == 8);
144-
}
145115
------
146116

147117
$(P Mixins can parameterize symbols using
@@ -161,6 +131,8 @@ void test()
161131
}
162132
------
163133

134+
$(H3 $(LNAME2 example, Example))
135+
164136
$(P This example uses a mixin to implement a generic Duff's device
165137
for an arbitrary statement (in this case, the arbitrary statement
166138
is in bold). A nested function is generated as well as a
@@ -234,6 +206,31 @@ void main()
234206
writeln("y = ", y); // prints 3
235207
}
236208
------
209+
)
210+
211+
$(P A mixin has its own scope, even if a declaration is overridden
212+
by the enclosing one:)
213+
214+
$(SPEC_RUNNABLE_EXAMPLE_RUN
215+
------
216+
import std.stdio : writeln;
217+
218+
int x = 4;
219+
220+
mixin template Foo()
221+
{
222+
int x = 5;
223+
int bar() { return x; }
224+
}
225+
226+
mixin Foo;
227+
228+
void main()
229+
{
230+
writeln("x = ", x); // prints 4
231+
writeln("bar() = ", bar()); // prints 5
232+
}
233+
------
237234
)
238235

239236
$(P If two different mixins are put in the same scope, and each
@@ -267,9 +264,11 @@ void main()
267264
------
268265
)
269266
$(P The call to $(D func()) is ambiguous because
270-
Foo.func and Bar.func are in different scopes.
267+
`Foo.func` and `Bar.func` are in different scopes.
271268
)
272269

270+
$(H3 $(LNAME2 resolving_ambiguities, Resolving Ambiguities))
271+
273272
$(P If a mixin has an $(I Identifier), it can be used to
274273
disambiguate between conflicting symbols:
275274
)
@@ -307,7 +306,8 @@ void main()
307306
}
308307
------
309308
)
310-
$(P Alias declarations can be used to overload together
309+
$(P Alias declarations can be used to form an
310+
$(DDSUBLINK spec/function, overload-sets, overload set) of
311311
functions declared in different mixins:)
312312

313313
-----
@@ -334,32 +334,41 @@ void main()
334334
}
335335
-----
336336

337+
$(H2 $(LNAME2 virtual_functions, Mixins and Virtual Functions))
337338

338-
$(P A mixin has its own scope, even if a declaration is overridden
339-
by the enclosing one:)
339+
$(P Mixins can add virtual functions to a class:)
340340

341341
$(SPEC_RUNNABLE_EXAMPLE_RUN
342342
------
343343
import std.stdio : writeln;
344344

345-
int x = 4;
346-
347345
mixin template Foo()
348346
{
349-
int x = 5;
350-
int bar() { return x; }
347+
void func() { writeln("Foo.func()"); }
351348
}
352349

353-
mixin Foo;
350+
class Bar
351+
{
352+
mixin Foo;
353+
}
354+
355+
class Code : Bar
356+
{
357+
override void func() { writeln("Code.func()"); }
358+
}
354359

355360
void main()
356361
{
357-
writeln("x = ", x); // prints 4
358-
writeln("bar() = ", bar()); // prints 5
362+
Bar b = new Bar();
363+
b.func(); // calls Foo.func()
364+
365+
b = new Code();
366+
b.func(); // calls Code.func()
359367
}
360368
------
361369
)
362370

371+
363372
$(SPEC_SUBNAV_PREV_NEXT template, Templates, contracts, Contract Programming)
364373
)
365374

0 commit comments

Comments
 (0)