Skip to content

Commit 63e54c8

Browse files
Resolve "break 075_type_derivation into chapters"
1 parent 33b6492 commit 63e54c8

File tree

8 files changed

+444
-723
lines changed

8 files changed

+444
-723
lines changed

courses/fundamentals_of_ada/075_type_derivation.rst

Lines changed: 40 additions & 440 deletions
Large diffs are not rendered by default.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
==============
2+
Introduction
3+
==============
4+
5+
-----------------
6+
Type Derivation
7+
-----------------
8+
9+
* Type :dfn:`derivation` allows for reusing code
10+
* Type can be **derived** from a **base type**
11+
* Base type can be substituted by the derived type
12+
* Subprograms defined on the base type are **inherited** on derived type
13+
* This is **not** OOP in Ada
14+
15+
- Tagged derivation **is** OOP in Ada
16+
17+
---------------------------
18+
Reminder: What is a Type?
19+
---------------------------
20+
21+
* A type is characterized by two elements
22+
23+
- Its data structure
24+
- The set of operations that applies to it
25+
26+
* The operations are called **primitive operations** in Ada
27+
28+
.. container:: latex_environment small
29+
30+
.. code:: Ada
31+
32+
package Types is
33+
type Integer_T is range -(2**63) .. 2**63-1 with Size => 64;
34+
procedure Increment_With_Truncation (Val : in out Integer_T);
35+
procedure Increment_With_Rounding (Val : in out Integer_T);
36+
end Types;
37+
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
===================
2+
Simple Derivation
3+
===================
4+
5+
------------------------
6+
Simple Type Derivation
7+
------------------------
8+
9+
* Any type (except :ada:`tagged`) can be derived
10+
11+
.. code:: Ada
12+
13+
type Natural_T is new Integer_T range 0 .. Integer_T'Last;
14+
15+
* :ada:`Natural_T` inherits from:
16+
17+
- The data **representation** of the parent
18+
19+
* Integer based, 64 bits
20+
21+
- The **primitives** of the parent
22+
23+
* :ada:`Increment_With_Truncation` and :ada:`Increment_With_Rounding`
24+
25+
* The types are not the same
26+
27+
.. code:: Ada
28+
29+
I_Obj : Integer_T := 0;
30+
N_Obj : Natural_T := 0;
31+
32+
* :ada:`I_Obj := N_Obj;` |rightarrow| generates a compile error
33+
34+
:color-red:`expected type "Integer_T" defined at line 2`
35+
36+
* But a child can be converted to the parent
37+
38+
* :ada:`I_Obj := Integer_T (N_Obj);`
39+
40+
--------------------------------------
41+
Simple Derivation and Type Structure
42+
--------------------------------------
43+
44+
* The type "structure" can not change
45+
46+
- :ada:`array` cannot become :ada:`record`
47+
- Integers cannot become floats
48+
49+
* But can be **constrained** further
50+
* Scalar ranges can be reduced
51+
52+
.. code:: Ada
53+
54+
type Positive_T is new Natural_T range 1 .. Natural_T'Last;
55+
56+
* Unconstrained types can be constrained
57+
58+
.. code:: Ada
59+
60+
type Arr_T is array (Integer range <>) of Integer;
61+
type Ten_Elem_Arr_T is new Arr_T (1 .. 10);
62+
type Rec_T (Size : Integer) is record
63+
Elem : Arr_T (1 .. Size);
64+
end record;
65+
type Ten_Elem_Rec_T is new Rec_T (10);
66+
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
============
2+
Primitives
3+
============
4+
5+
--------------------
6+
Primitive Operations
7+
--------------------
8+
9+
* Primitive Operations are those subprograms associated with a type
10+
11+
.. code:: Ada
12+
13+
type Integer_T is range -(2**63) .. 2**63-1 with Size => 64;
14+
procedure Increment_With_Truncation (Val : in out Integer_T);
15+
procedure Increment_With_Rounding (Val : in out Integer_T);
16+
17+
* Most types have some primitive operations defined by the language
18+
19+
* e.g. equality operators for most types, numeric operators for integers and floats
20+
21+
* A primitive operation on the parent can receive an object of a child type with no conversion
22+
23+
.. code:: Ada
24+
25+
declare
26+
N_Obj : Natural_T := 1234;
27+
begin
28+
Increment_With_Truncation (N_Obj);
29+
end;
30+
31+
---------------------------------------
32+
General Rule for Defining a Primitive
33+
---------------------------------------
34+
35+
* Primitives are subprograms
36+
* Subprogram :ada:`S` is a primitive of type :ada:`T` if and only if:
37+
38+
- :ada:`S` is declared in the scope of :ada:`T`
39+
- :ada:`S` uses type :ada:`T`
40+
41+
+ As a parameter
42+
+ As its return type (for a :ada:`function`)
43+
44+
- :ada:`S` is above :dfn:`freeze-point` (see next section)
45+
46+
* Standard practice
47+
48+
- Primitives should be declared **right after** the type itself
49+
- In a scope, declare at most a **single** type with primitives
50+
51+
.. code:: Ada
52+
53+
package P is
54+
type T is range 1 .. 10;
55+
procedure P1 (V : T);
56+
procedure P2 (V1 : Integer; V2 : T);
57+
function F return T;
58+
end P;
59+
60+
------------------------------
61+
Primitive of Multiple Types
62+
------------------------------
63+
64+
A subprogram can be a primitive of several types
65+
66+
.. code:: Ada
67+
68+
package P is
69+
type Distance_T is range 0 .. 9999;
70+
type Percentage_T is digits 2 range 0.0 .. 1.0;
71+
type Units_T is (Meters, Feet, Furlongs);
72+
73+
procedure Convert (Value : in out Distance_T;
74+
Source : Units_T;
75+
Result : Units_T;
76+
procedure Shrink (Value : in out Distance_T;
77+
Percent : Percentage_T);
78+
79+
end P;
80+
81+
* :ada:`Convert` and :ada:`Shrink` are primitives for :ada:`Distance_T`
82+
* :ada:`Convert` is also a primitive of :ada:`Units_T`
83+
* :ada:`Shrink` is also a primitive of :ada:`Percentage_T`
84+
85+
----------------------------------
86+
Creating Primitives for Children
87+
----------------------------------
88+
89+
* Just because we can inherit a primitive from out parent doesn't mean we want to
90+
91+
* We can create a new primitive (with the same name as the parent) for the child
92+
93+
* Very similar to overloaded subprograms
94+
* But added benefit of visibility to grandchildren
95+
96+
* We can also remove a primitive (see next slide)
97+
98+
.. code:: Ada
99+
100+
type Integer_T is range -(2**63) .. 2**63-1;
101+
procedure Increment_With_Truncation (Val : in out Integer_T);
102+
procedure Increment_With_Rounding (Val : in out Integer_T);
103+
104+
type Child_T is new Integer_T range -1000 .. 1000;
105+
procedure Increment_With_Truncation (Val : in out Child_T);
106+
107+
type Grandchild_T is new Child_T range -100 .. 100;
108+
procedure Increment_With_Rounding (Val : in out Grandchild_T);
109+
110+
------------------------
111+
Overriding Indications
112+
------------------------
113+
114+
* **Optional** indications
115+
* Checked by compiler
116+
117+
.. container:: latex_environment footnotesize
118+
119+
.. code:: Ada
120+
121+
type Child_T is new Integer_T range -1000 .. 1000;
122+
procedure Increment_With_Truncation
123+
(Val : in out Child_T);
124+
procedure Just_For_Child
125+
(Val : in out Child_T);
126+
127+
* **Replacing** a primitive: :ada:`overriding` indication
128+
129+
.. container:: latex_environment footnotesize
130+
131+
.. code:: Ada
132+
133+
overriding procedure Increment_With_Truncation
134+
(Val : in out Child_T);
135+
136+
* **Adding** a primitive: :ada:`not overriding` indication
137+
138+
.. container:: latex_environment footnotesize
139+
140+
.. code:: Ada
141+
142+
not overriding procedure Just_For_Child
143+
(Val : in out Child_T);
144+
145+
* **Removing** a primitive: :ada:`overriding` as :ada:`abstract`
146+
147+
.. container:: latex_environment footnotesize
148+
149+
.. code:: Ada
150+
151+
overriding procedure Just_For_Child
152+
(Val : in out Grandchild_T) is abstract;
153+
154+
* Using :ada:`overriding` or :ada:`not overriding` incorrectly will generate a compile error
155+
156+
..
157+
language_version 2005
158+
159+
------
160+
Quiz
161+
------
162+
163+
.. include:: ../quiz/operators_override_simple/quiz.rst
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
==============
2+
Freeze Point
3+
==============
4+
5+
-----------------------------
6+
What is the "Freeze Point"?
7+
-----------------------------
8+
9+
* Ada doesn't explicitly identify the end of the "scope" of a type
10+
11+
* The compiler needs to know it for determining primitive operations
12+
* Also needed for other situations (described elsewhere)
13+
14+
* This end is the implicit **freeze point** occurring whenever:
15+
16+
- A **variable** of the type is **declared**
17+
- The type is **derived**
18+
- The **end of the scope** is reached
19+
20+
* Subprograms past this "freeze point" are not primitive operations
21+
22+
.. code:: Ada
23+
24+
type Parent is Integer;
25+
procedure Prim (V : Parent);
26+
27+
type Child is new Parent;
28+
29+
-- Parent has been derived, so it is frozen.
30+
-- Prim2 is not a primitive
31+
procedure Prim2 (V : Parent);
32+
33+
V : Child;
34+
35+
-- Child used in an object declaration, so it is frozen
36+
-- Prim3 is not a primitive
37+
procedure Prim3 (V : Child);
38+
39+
-----------------------
40+
Debugging Type Freeze
41+
-----------------------
42+
43+
* Freeze |rightarrow| Type **completely** defined
44+
* Compiler does **need** to determine the freeze point
45+
46+
- To instantiate, derive, get info on the type (:ada:`'Size`)...
47+
- Freeze rules are a guide to place it
48+
- Actual choice is more technical
49+
50+
+ May contradict the standard
51+
52+
* :command:`-gnatDG` to get **expanded** source
53+
54+
- **Pseudo-Ada** debug information
55+
56+
:filename:`pkg.ads`
57+
58+
.. code:: Ada
59+
60+
type Up_To_Eleven is range 0 .. 11;
61+
62+
:filename:`<obj>/pkg.ads.dg`
63+
64+
.. container:: latex_environment tiny
65+
66+
::
67+
68+
type example__up_to_eleven_t is range 0 .. 11; -- type declaration
69+
[type example__Tup_to_eleven_tB is new short_short_integer] -- representation
70+
freeze example__Tup_to_eleven_tB [] -- freeze representation
71+
freeze example__up_to_eleven_t [] -- freeze representation
72+
73+
------
74+
Quiz
75+
------
76+
77+
.. container:: latex_environment tiny
78+
79+
.. code:: Ada
80+
81+
type Parent is range 1 .. 100;
82+
procedure Proc_A (X : in out Parent);
83+
84+
type Child is new Parent range 2 .. 99;
85+
procedure Proc_B (X : in out Parent);
86+
procedure Proc_B (X : in out Child);
87+
88+
-- Other scope
89+
procedure Proc_C (X : in out Child);
90+
91+
type Grandchild is new Child range 3 .. 98;
92+
93+
procedure Proc_C (X : in out Grandchild);
94+
95+
.. container:: columns
96+
97+
.. container:: column
98+
99+
Which are :ada:`Parent`'s primitives?
100+
101+
A. :answermono:`Proc_A`
102+
B. ``Proc_B``
103+
C. ``Proc_C``
104+
D. No primitives of :ada:`Parent`
105+
106+
.. container:: column
107+
108+
.. container:: animate
109+
110+
Explanations
111+
112+
A. Correct
113+
B. Freeze: :ada:`Parent` has been derived
114+
C. Freeze: scope change
115+
D. Incorrect
116+
117+

0 commit comments

Comments
 (0)