Skip to content

Commit c556d36

Browse files
authored
[spec] Improve *AliasDeclaration* docs (#3171)
* [spec] Improve *AliasDeclaration* docs Define aliases in terms of another symbol, not just another type. Add subheadings. Capitalize type names & add note about doing this. Move paragraph about type aliases being indistinguishable from other aliases up to type aliases section. Move function type aliases example down to function type aliases section. Make 2 examples runnable. Simplify aliasing an overload set example. Make AliasAssign sections child headings of AliasDeclaration. * Make AliasAssign examples get compiled Add static assert with staticMap and T.sizeof. * Use std.meta, fix capitalization * Allow lowercase aliases of basic type names
1 parent be37442 commit c556d36

File tree

1 file changed

+72
-50
lines changed

1 file changed

+72
-50
lines changed

spec/declaration.dd

Lines changed: 72 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,12 @@ $(GNAME AliasAssignment):
281281
$(GLINK_LEX Identifier) $(GLINK2 template, TemplateParameters)$(OPT) $(D =) $(GLINK StorageClasses)$(OPT) $(GLINK2 type, BasicType) $(GLINK2 function, Parameters) $(GLINK2 function, MemberFunctionAttributes)$(OPT)
282282
)
283283

284-
$(P $(I AliasDeclaration)s create a symbol that is an alias for another type,
285-
and can be used anywhere that other type may appear.
284+
$(P $(I AliasDeclaration)s create a symbol name that refers to another symbol.
285+
That symbol name can be used anywhere that the aliased symbol may appear.
286286
)
287287

288+
$(H3 $(LNAME2 alias-type, Type Aliases))
289+
288290
--------------------
289291
alias myint = abc.Foo.bar;
290292
--------------------
@@ -302,6 +304,20 @@ void foo(int x) { ... }
302304
void foo(myint m) { ... } // error, multiply defined function foo
303305
--------------------
304306

307+
$(P
308+
Type aliases can sometimes look indistinguishable from
309+
other symbol aliases:
310+
)
311+
312+
--------------------
313+
alias abc = foo.bar; // is it a type or a symbol?
314+
--------------------
315+
316+
$(BEST_PRACTICE Other than when aliasing simple basic type names,
317+
type alias names should be Capitalized.)
318+
319+
$(H3 $(LNAME2 alias-symbol, Symbol Aliases))
320+
305321
$(P A symbol can be declared as an $(I alias) of another symbol.
306322
For example:
307323
)
@@ -329,16 +345,7 @@ t1.t v1; // v1 is type int
329345
t2 v2; // v2 is type int
330346
t3 v3; // v3 is type int
331347
t4 v4; // v4 is type int
332-
333-
alias Fun = int(string p);
334-
int fun(string){return 0;}
335-
static assert(is(typeof(fun) == Fun));
336-
337-
alias MemberFun1 = int() const;
338-
alias MemberFun2 = const int();
339-
// leading attributes apply to the func, not the return type
340-
static assert(is(MemberFun1 == MemberFun2));
341-
--------------------
348+
---
342349

343350
$(P
344351
Aliased symbols are useful as a shorthand for a long qualified
@@ -366,57 +373,44 @@ version (linux)
366373
alias strlen = string.strlen;
367374
--------------------
368375

376+
$(H3 $(LNAME2 alias-overload, Aliasing an Overload Set))
377+
369378
$(P
370379
Aliases can also `import` a set of overloaded functions, that can
371380
be overloaded with functions in the current scope:
372381
)
373382

383+
$(SPEC_RUNNABLE_EXAMPLE_RUN
374384
--------------------
375-
class A
385+
class B
376386
{
377-
int foo(int a) { return 1; }
378-
}
379-
380-
class B : A
381-
{
382-
int foo( int a, uint b ) { return 2; }
387+
int foo(int a, uint b) { return 2; }
383388
}
384389

385390
class C : B
386391
{
387-
int foo( int a ) { return 3; }
392+
// declaring an overload hides any base class overloads
393+
int foo(int a) { return 3; }
394+
// redeclare hidden overload
388395
alias foo = B.foo;
389396
}
390397

391-
class D : C
392-
{
393-
}
394-
395-
void test()
398+
void main()
396399
{
397-
D b = new D();
398-
int i;
400+
import std.stdio;
399401

400-
i = b.foo(1, 2u); // calls B.foo
401-
i = b.foo(1); // calls C.foo
402+
C c = new C();
403+
c.foo(1, 2u).writeln; // calls B.foo
404+
c.foo(1).writeln; // calls C.foo
402405
}
403406
--------------------
407+
)
404408

405-
$(P
406-
$(B Note:) Type aliases can sometimes look indistinguishable from
407-
alias declarations:
408-
)
409-
410-
--------------------
411-
alias abc = foo.bar; // is it a type or a symbol?
412-
--------------------
413-
414-
$(P
415-
The distinction is made in the semantic analysis pass.
416-
)
409+
$(H3 $(LNAME2 alias-variable, Aliasing Variables))
417410

418411
$(P Aliases cannot be used for expressions:)
419412

413+
$(SPEC_RUNNABLE_EXAMPLE_RUN
420414
-----------
421415
struct S
422416
{
@@ -426,10 +420,27 @@ struct S
426420

427421
alias a = S.i; // OK, `S.i` is a symbol
428422
alias b = S.j; // OK. `S.j` is also a symbol
429-
alias c = a + b; // illegal, `a + b` is an expression
423+
//alias c = a + b; // illegal, `a + b` is an expression
430424
a = 2; // sets `S.i` to `2`
431425
b = 4; // sets `S.j` to `4`
426+
assert(S.i == 2);
427+
assert(S.j == 4);
432428
-----------
429+
)
430+
431+
$(H3 $(LNAME2 alias-function, Aliasing a Function Type))
432+
433+
$(P Function types can be aliased:)
434+
---
435+
alias Fun = int(string p);
436+
int fun(string){return 0;}
437+
static assert(is(typeof(fun) == Fun));
438+
439+
alias MemberFun1 = int() const;
440+
alias MemberFun2 = const int();
441+
// leading attributes apply to the func, not the return type
442+
static assert(is(MemberFun1 == MemberFun2));
443+
--------------------
433444

434445
$(P Aliases can be used to call a function with different default
435446
arguments, change an argument from required to default or vice versa:)
@@ -467,7 +478,7 @@ void barbar(int a, int b = 6, int c = 7) {
467478
-----------
468479
)
469480

470-
$(H2 $(LNAME2 AliasAssign, Alias Assign))
481+
$(H3 $(LNAME2 AliasAssign, Alias Assign))
471482

472483
$(GRAMMAR
473484
$(GNAME AliasAssign):
@@ -477,6 +488,7 @@ $(GNAME AliasAssign):
477488
$(P An $(GLINK AliasDeclaration) can have a new value assigned to it with an
478489
$(I AliasAssign):)
479490

491+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
480492
---
481493
template Gorgon(T)
482494
{
@@ -486,6 +498,7 @@ template Gorgon(T)
486498
}
487499
pragma(msg, Gorgon!int); // prints int
488500
---
501+
)
489502

490503
$(UL
491504
$(LI The $(I AliasAssign) and its corresponding $(I AliasDeclaration) must both be
@@ -505,9 +518,11 @@ to another $(I AliasAssign) to the same lvalue other than in the right hand side
505518
$(I AliasAssign) is particularly useful when using an iterative
506519
computation rather than a recursive one, as it avoids creating
507520
the large number of intermediate templates that the recursive one
508-
engenders.
521+
engenders.)
522+
523+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
509524
---
510-
template AliasSeq(T...) { alias AliasSeq = T; }
525+
import std.meta : AliasSeq;
511526

512527
static if (0) // recursive method for comparison
513528
{
@@ -534,9 +549,9 @@ enum X = 3;
534549
alias TK = Reverse!(int, const uint, X);
535550
pragma(msg, TK); // prints tuple(3, (const(uint)), (int))
536551
---
537-
)
552+
)
538553

539-
$(H2 $(LNAME2 alias-reassignment, Alias Reassignment))
554+
$(H3 $(LNAME2 alias-reassignment, Alias Reassignment))
540555

541556
$(GRAMMAR
542557
$(GNAME AliasReassignment):
@@ -547,15 +562,22 @@ $(GNAME AliasReassignment):
547562

548563
$(P An alias declaration inside a template can be reassigned a new value.)
549564

565+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
550566
---
551-
template staticMap(alias F, T...)
567+
import std.meta : AliasSeq;
568+
569+
template staticMap(alias F, Args...)
552570
{
553571
alias A = AliasSeq!();
554-
static foreach (t; T)
555-
A = AliasSeq!(A, F!T); // alias reassignment
572+
static foreach (Arg; Args)
573+
A = AliasSeq!(A, F!Arg); // alias reassignment
556574
alias staticMap = A;
557575
}
576+
577+
enum size(T) = T.sizeof;
578+
static assert(staticMap!(size, char, wchar, dchar) == AliasSeq!(1, 2, 4));
558579
---
580+
)
559581

560582
$(P The $(I Identifier) must resolve to a lexically preceding $(GLINK AliasDeclaration).
561583
Both must be members of the same $(GLINK2 template, TemplateDeclaration).

0 commit comments

Comments
 (0)