Repository navigation
Expand file tree
/
Copy pathnamespaces.cm
More file actions
192 lines (149 loc) · 6.63 KB
/
Copy pathnamespaces.cm
File metadata and controls
192 lines (149 loc) · 6.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
##
Namespaces, and what they are for.
A namespace is a place a name sits in. Two of them may each hold a Circle, and the two are
different types that never have to know about each other. That is what a namespace is for,
and nearly all of what it does.
Everything else follows from one rule: a bare name is read from where it is written, then
outward, ending at the global namespace. Nearest wins.
A remark rather than documentation: the next thing below is a 'using', which declares
nothing to hang a summary on. The namespaces themselves carry theirs.
##
##
A using shortens names from one namespace, for one file. It brings in no code and compiles
no extra file — it only decides which names this file can write without qualifying. Here it
makes a bare 'Circle' mean the flat one.
##
using Geometry.Flat;
##
@summary: Shapes, and the arithmetic that goes with them.
@remarks: The file-scoped form. Everything below belongs to Geometry, and there is no
closer because there is nothing after it to close.
A namespace written inside this one is a child of it rather than a second beside it, so the
file says what it is once at the top, and then says where within itself each piece sits.
##
namespace Geometry;
##
Declared in Geometry itself, so both namespaces below reach it with nothing written: the
walk outward from each of them passes through here.
This is what keeps a namespace a place to put things rather than a barrier around them. A
child reaches its parent with nothing written; a parent reaches into a child only by
naming it.
##
public abstract model Shape
# @summary: What this shape is called.
protected string name;
# @summary: Names a shape.
# @label: what to call it.
public function Shape(string label)
this.name = label;
end function
# @summary: How much the shape covers, which each kind answers for itself.
# @yields: the area, nothing for a shape of no particular kind.
public virtual real function Area()
yield 0.0;
end function
# @summary: What a shape prints as.
# @yields: its name and its area, rounded.
public override string function ToString()
yield this.name + " of area " + Math.Round(this.Area());
end function
end model
# @summary: Shapes that sit flat on a page.
namespace Flat
##
Written as Geometry.Flat.Circle from outside, and as Circle from anywhere already inside
Geometry.Flat. It extends Shape, which is not declared here — that name is found by
walking out one level.
##
public model Circle extends Shape
real radius;
# @summary: A flat circle of the given radius.
# @radius: how far it reaches from its center.
public function Circle(real radius)
base("a flat circle");
this.radius = radius;
end function
# @summary: The area a flat circle covers.
# @yields: pi times the radius squared.
public override real function Area()
yield Math.Pi * this.radius * this.radius;
end function
end model
end namespace
# @summary: Shapes that take up room.
namespace Solid
##
A second Circle, and nothing about it collides with the first. Their full names are
Geometry.Flat.Circle and Geometry.Solid.Circle, so the compiler never has to guess, and
a reader who needs both says which one is meant.
##
public model Circle extends Shape
real radius;
# @summary: A sphere of the given radius.
# @radius: how far it reaches from its center.
public function Circle(real radius)
base("a sphere");
this.radius = radius;
end function
# @summary: The surface area of a sphere, which is four times the flat circle's.
# @yields: four pi times the radius squared.
public override real function Area()
yield 4.0 * Math.Pi * this.radius * this.radius;
end function
end model
end namespace
shared model Program
function Main()
Program.WhatTheUsingDecides();
Program.WhatQualifyingReaches();
Program.WhatTheyShare();
Program.WhereStandardSits();
end function
# ---- A using picks one namespace's names ---------------------------------------
##
'Circle' with nothing in front of it is the flat one, because that is the namespace the
file wrote a using for. Take the using away and this line stops compiling — it does not
quietly become the other Circle.
##
function WhatTheUsingDecides()
Circle flat = new Circle(2.0);
Console.WriteLine("a bare Circle is " + flat);
end function
# ---- Qualifying reaches past it -------------------------------------------------
##
Writing the namespace in front reaches a type no using named. Two spellings work, and
both mean the same type: 'Solid' is read outward from here, finds Geometry.Solid, and
stops; 'Geometry.Solid' says the whole path and needs nothing found for it.
##
function WhatQualifyingReaches()
Solid.Circle nearby = new Solid.Circle(2.0);
Geometry.Solid.Circle spelledOut = new Geometry.Solid.Circle(2.0);
Console.WriteLine("Solid.Circle is " + nearby);
Console.WriteLine("and so is Geometry.Solid.Circle: " + spelledOut);
Console.WriteLine("the two are equal: " + (nearby == spelledOut));
end function
# ---- What they have in common ----------------------------------------------------
##
Both Circles extend the same Shape, so both fit in one set of them. A namespace divides
names, not types: it decides what a program has to write, and changes nothing about what
the program then does.
##
function WhatTheyShare()
Shape[] shapes = {new Circle(1.0), new Solid.Circle(1.0)};
Console.WriteLine("both are a Shape, so both fit in one set of them:");
loop each shape in shapes
Console.WriteLine(" " + shape);
end loop
end function
# ---- The one namespace nobody declares ---------------------------------------------
##
Everything the language provides sits in Standard, which is in scope in every file
without a using. It can still be named, and naming it is how a program reaches Math when
it has declared a Math of its own.
##
function WhereStandardSits()
Console.WriteLine("Math.Pi is " + Math.Pi);
Console.WriteLine("Standard.Math.Pi is " + Standard.Math.Pi);
Console.WriteLine("the same value: " + (Math.Pi == Standard.Math.Pi));
end function
end model