diff --git a/courses/fundamentals_of_ada/075_type_derivation.rst b/courses/fundamentals_of_ada/075_type_derivation.rst index a5c9d848f..656fe2294 100644 --- a/courses/fundamentals_of_ada/075_type_derivation.rst +++ b/courses/fundamentals_of_ada/075_type_derivation.rst @@ -1,440 +1,40 @@ -*************** -Type Derivation -*************** - -.. container:: PRELUDE BEGIN - -.. container:: PRELUDE ROLES - -.. role:: ada(code) - :language: Ada - -.. role:: C(code) - :language: C - -.. role:: cpp(code) - :language: C++ - -.. container:: PRELUDE SYMBOLS - -.. |rightarrow| replace:: :math:`\rightarrow` -.. |forall| replace:: :math:`\forall` -.. |exists| replace:: :math:`\exists` -.. |equivalent| replace:: :math:`\iff` -.. |le| replace:: :math:`\le` -.. |ge| replace:: :math:`\ge` -.. |lt| replace:: :math:`<` -.. |gt| replace:: :math:`>` -.. |checkmark| replace:: :math:`\checkmark` - -.. container:: PRELUDE REQUIRES - -.. container:: PRELUDE PROVIDES - -.. container:: PRELUDE END - -============== -Introduction -============== - ------------------ -Type Derivation ------------------ - -* Type :dfn:`derivation` allows for reusing code -* Type can be **derived** from a **base type** -* Base type can be substituted by the derived type -* Subprograms defined on the base type are **inherited** on derived type -* This is **not** OOP in Ada - - - Tagged derivation **is** OOP in Ada - ---------------------------- -Reminder: What is a Type? ---------------------------- - -* A type is characterized by two elements - - - Its data structure - - The set of operations that applies to it - -* The operations are called **primitive operations** in Ada - -.. container:: latex_environment small - - .. code:: Ada - - package Types is - type Integer_T is range -(2**63) .. 2**63-1 with Size => 64; - procedure Increment_With_Truncation (Val : in out Integer_T); - procedure Increment_With_Rounding (Val : in out Integer_T); - end Types; - -=================== -Simple Derivation -=================== - ------------------------- -Simple Type Derivation ------------------------- - -* Any type (except :ada:`tagged`) can be derived - - .. code:: Ada - - type Natural_T is new Integer_T range 0 .. Integer_T'Last; - -* :ada:`Natural_T` inherits from: - - - The data **representation** of the parent - - * Integer based, 64 bits - - - The **primitives** of the parent - - * :ada:`Increment_With_Truncation` and :ada:`Increment_With_Rounding` - -* The types are not the same - - .. code:: Ada - - I_Obj : Integer_T := 0; - N_Obj : Natural_T := 0; - - * :ada:`I_Obj := N_Obj;` |rightarrow| generates a compile error - - :color-red:`expected type "Integer_T" defined at line 2` - - * But a child can be converted to the parent - - * :ada:`I_Obj := Integer_T (N_Obj);` - --------------------------------------- -Simple Derivation and Type Structure --------------------------------------- - -* The type "structure" can not change - - - :ada:`array` cannot become :ada:`record` - - Integers cannot become floats - -* But can be **constrained** further -* Scalar ranges can be reduced - - .. code:: Ada - - type Positive_T is new Natural_T range 1 .. Natural_T'Last; - -* Unconstrained types can be constrained - - .. code:: Ada - - type Arr_T is array (Integer range <>) of Integer; - type Ten_Elem_Arr_T is new Arr_T (1 .. 10); - type Rec_T (Size : Integer) is record - Elem : Arr_T (1 .. Size); - end record; - type Ten_Elem_Rec_T is new Rec_T (10); - -============ -Primitives -============ - --------------------- -Primitive Operations --------------------- - -* Primitive Operations are those subprograms associated with a type - -.. code:: Ada - - type Integer_T is range -(2**63) .. 2**63-1 with Size => 64; - procedure Increment_With_Truncation (Val : in out Integer_T); - procedure Increment_With_Rounding (Val : in out Integer_T); - -* Most types have some primitive operations defined by the language - - * e.g. equality operators for most types, numeric operators for integers and floats - -* A primitive operation on the parent can receive an object of a child type with no conversion - - .. code:: Ada - - declare - N_Obj : Natural_T := 1234; - begin - Increment_With_Truncation (N_Obj); - end; - ---------------------------------------- -General Rule for Defining a Primitive ---------------------------------------- - -* Primitives are subprograms -* Subprogram :ada:`S` is a primitive of type :ada:`T` if and only if: - - - :ada:`S` is declared in the scope of :ada:`T` - - :ada:`S` uses type :ada:`T` - - + As a parameter - + As its return type (for a :ada:`function`) - - - :ada:`S` is above :dfn:`freeze-point` (see next section) - -* Standard practice - - - Primitives should be declared **right after** the type itself - - In a scope, declare at most a **single** type with primitives - - .. code:: Ada - - package P is - type T is range 1 .. 10; - procedure P1 (V : T); - procedure P2 (V1 : Integer; V2 : T); - function F return T; - end P; - ------------------------------- -Primitive of Multiple Types ------------------------------- - -A subprogram can be a primitive of several types - - .. code:: Ada - - package P is - type Distance_T is range 0 .. 9999; - type Percentage_T is digits 2 range 0.0 .. 1.0; - type Units_T is (Meters, Feet, Furlongs); - - procedure Convert (Value : in out Distance_T; - Source : Units_T; - Result : Units_T; - procedure Shrink (Value : in out Distance_T; - Percent : Percentage_T); - - end P; - -* :ada:`Convert` and :ada:`Shrink` are primitives for :ada:`Distance_T` -* :ada:`Convert` is also a primitive of :ada:`Units_T` -* :ada:`Shrink` is also a primitive of :ada:`Percentage_T` - ----------------------------------- -Creating Primitives for Children ----------------------------------- - -* Just because we can inherit a primitive from out parent doesn't mean we want to - -* We can create a new primitive (with the same name as the parent) for the child - - * Very similar to overloaded subprograms - * But added benefit of visibility to grandchildren - -* We can also remove a primitive (see next slide) - -.. code:: Ada - - type Integer_T is range -(2**63) .. 2**63-1; - procedure Increment_With_Truncation (Val : in out Integer_T); - procedure Increment_With_Rounding (Val : in out Integer_T); - - type Child_T is new Integer_T range -1000 .. 1000; - procedure Increment_With_Truncation (Val : in out Child_T); - - type Grandchild_T is new Child_T range -100 .. 100; - procedure Increment_With_Rounding (Val : in out Grandchild_T); - ------------------------- -Overriding Indications ------------------------- - -* **Optional** indications -* Checked by compiler - - .. container:: latex_environment footnotesize - - .. code:: Ada - - type Child_T is new Integer_T range -1000 .. 1000; - procedure Increment_With_Truncation - (Val : in out Child_T); - procedure Just_For_Child - (Val : in out Child_T); - -* **Replacing** a primitive: :ada:`overriding` indication - - .. container:: latex_environment footnotesize - - .. code:: Ada - - overriding procedure Increment_With_Truncation - (Val : in out Child_T); - -* **Adding** a primitive: :ada:`not overriding` indication - - .. container:: latex_environment footnotesize - - .. code:: Ada - - not overriding procedure Just_For_Child - (Val : in out Child_T); - -* **Removing** a primitive: :ada:`overriding` as :ada:`abstract` - - .. container:: latex_environment footnotesize - - .. code:: Ada - - overriding procedure Just_For_Child - (Val : in out Grandchild_T) is abstract; - -* Using :ada:`overriding` or :ada:`not overriding` incorrectly will generate a compile error - -.. - language_version 2005 - ------- -Quiz ------- - -.. include:: quiz/operators_override_simple/quiz.rst - -============== -Freeze Point -============== - ------------------------------ -What is the "Freeze Point"? ------------------------------ - -* Ada doesn't explicitly identify the end of the "scope" of a type - - * The compiler needs to know it for determining primitive operations - * Also needed for other situations (described elsewhere) - -* This end is the implicit **freeze point** occurring whenever: - - - A **variable** of the type is **declared** - - The type is **derived** - - The **end of the scope** is reached - -* Subprograms past this "freeze point" are not primitive operations - -.. code:: Ada - - type Parent is Integer; - procedure Prim (V : Parent); - - type Child is new Parent; - - -- Parent has been derived, so it is frozen. - -- Prim2 is not a primitive - procedure Prim2 (V : Parent); - - V : Child; - - -- Child used in an object declaration, so it is frozen - -- Prim3 is not a primitive - procedure Prim3 (V : Child); - ------------------------ -Debugging Type Freeze ------------------------ - -* Freeze |rightarrow| Type **completely** defined -* Compiler does **need** to determine the freeze point - - - To instantiate, derive, get info on the type (:ada:`'Size`)... - - Freeze rules are a guide to place it - - Actual choice is more technical - - + May contradict the standard - -* :command:`-gnatDG` to get **expanded** source - - - **Pseudo-Ada** debug information - -:filename:`pkg.ads` - - .. code:: Ada - - type Up_To_Eleven is range 0 .. 11; - -:filename:`/pkg.ads.dg` - -.. container:: latex_environment tiny - - :: - - type example__up_to_eleven_t is range 0 .. 11; -- type declaration - [type example__Tup_to_eleven_tB is new short_short_integer] -- representation - freeze example__Tup_to_eleven_tB [] -- freeze representation - freeze example__up_to_eleven_t [] -- freeze representation - ------- -Quiz ------- - -.. container:: latex_environment tiny - - .. code:: Ada - - type Parent is range 1 .. 100; - procedure Proc_A (X : in out Parent); - - type Child is new Parent range 2 .. 99; - procedure Proc_B (X : in out Parent); - procedure Proc_B (X : in out Child); - - -- Other scope - procedure Proc_C (X : in out Child); - - type Grandchild is new Child range 3 .. 98; - - procedure Proc_C (X : in out Grandchild); - -.. container:: columns - - .. container:: column - - Which are :ada:`Parent`'s primitives? - - A. :answermono:`Proc_A` - B. ``Proc_B`` - C. ``Proc_C`` - D. No primitives of :ada:`Parent` - - .. container:: column - - .. container:: animate - - Explanations - - A. Correct - B. Freeze: :ada:`Parent` has been derived - C. Freeze: scope change - D. Incorrect - - -========= -Summary -========= - ---------- -Summary ---------- - -* :dfn:`Primitive` of a type - - - Subprogram above **freeze-point** that takes or returns the type - - Can be a primitive for **multiple types** - -* Freeze point rules can be tricky -* Simple type derivation - - - Types derived from other types can only **add limitations** - - + Constraints, ranges - + Cannot change underlying structure - +*************** +Type Derivation +*************** + +.. container:: PRELUDE BEGIN + +.. container:: PRELUDE ROLES + +.. role:: ada(code) + :language: Ada + +.. role:: C(code) + :language: C + +.. role:: cpp(code) + :language: C++ + +.. container:: PRELUDE SYMBOLS + +.. |rightarrow| replace:: :math:`\rightarrow` +.. |forall| replace:: :math:`\forall` +.. |exists| replace:: :math:`\exists` +.. |equivalent| replace:: :math:`\iff` +.. |le| replace:: :math:`\le` +.. |ge| replace:: :math:`\ge` +.. |lt| replace:: :math:`<` +.. |gt| replace:: :math:`>` +.. |checkmark| replace:: :math:`\checkmark` + +.. container:: PRELUDE REQUIRES + +.. container:: PRELUDE PROVIDES + +.. container:: PRELUDE END + +.. include:: 075_type_derivation/01-introduction.rst +.. include:: 075_type_derivation/02-simple_derivation.rst +.. include:: 075_type_derivation/03-primitives.rst +.. include:: 075_type_derivation/04-freeze_point.rst +.. include:: 075_type_derivation/99-summary.rst diff --git a/courses/fundamentals_of_ada/075_type_derivation/01-introduction.rst b/courses/fundamentals_of_ada/075_type_derivation/01-introduction.rst new file mode 100644 index 000000000..a96d3d20b --- /dev/null +++ b/courses/fundamentals_of_ada/075_type_derivation/01-introduction.rst @@ -0,0 +1,37 @@ +============== +Introduction +============== + +----------------- +Type Derivation +----------------- + +* Type :dfn:`derivation` allows for reusing code +* Type can be **derived** from a **base type** +* Base type can be substituted by the derived type +* Subprograms defined on the base type are **inherited** on derived type +* This is **not** OOP in Ada + + - Tagged derivation **is** OOP in Ada + +--------------------------- +Reminder: What is a Type? +--------------------------- + +* A type is characterized by two elements + + - Its data structure + - The set of operations that applies to it + +* The operations are called **primitive operations** in Ada + +.. container:: latex_environment small + + .. code:: Ada + + package Types is + type Integer_T is range -(2**63) .. 2**63-1 with Size => 64; + procedure Increment_With_Truncation (Val : in out Integer_T); + procedure Increment_With_Rounding (Val : in out Integer_T); + end Types; + diff --git a/courses/fundamentals_of_ada/075_type_derivation/02-simple_derivation.rst b/courses/fundamentals_of_ada/075_type_derivation/02-simple_derivation.rst new file mode 100644 index 000000000..d1dacaef8 --- /dev/null +++ b/courses/fundamentals_of_ada/075_type_derivation/02-simple_derivation.rst @@ -0,0 +1,66 @@ +=================== +Simple Derivation +=================== + +------------------------ +Simple Type Derivation +------------------------ + +* Any type (except :ada:`tagged`) can be derived + + .. code:: Ada + + type Natural_T is new Integer_T range 0 .. Integer_T'Last; + +* :ada:`Natural_T` inherits from: + + - The data **representation** of the parent + + * Integer based, 64 bits + + - The **primitives** of the parent + + * :ada:`Increment_With_Truncation` and :ada:`Increment_With_Rounding` + +* The types are not the same + + .. code:: Ada + + I_Obj : Integer_T := 0; + N_Obj : Natural_T := 0; + + * :ada:`I_Obj := N_Obj;` |rightarrow| generates a compile error + + :color-red:`expected type "Integer_T" defined at line 2` + + * But a child can be converted to the parent + + * :ada:`I_Obj := Integer_T (N_Obj);` + +-------------------------------------- +Simple Derivation and Type Structure +-------------------------------------- + +* The type "structure" can not change + + - :ada:`array` cannot become :ada:`record` + - Integers cannot become floats + +* But can be **constrained** further +* Scalar ranges can be reduced + + .. code:: Ada + + type Positive_T is new Natural_T range 1 .. Natural_T'Last; + +* Unconstrained types can be constrained + + .. code:: Ada + + type Arr_T is array (Integer range <>) of Integer; + type Ten_Elem_Arr_T is new Arr_T (1 .. 10); + type Rec_T (Size : Integer) is record + Elem : Arr_T (1 .. Size); + end record; + type Ten_Elem_Rec_T is new Rec_T (10); + diff --git a/courses/fundamentals_of_ada/075_type_derivation/03-primitives.rst b/courses/fundamentals_of_ada/075_type_derivation/03-primitives.rst new file mode 100644 index 000000000..dfa16dca6 --- /dev/null +++ b/courses/fundamentals_of_ada/075_type_derivation/03-primitives.rst @@ -0,0 +1,163 @@ +============ +Primitives +============ + +-------------------- +Primitive Operations +-------------------- + +* Primitive Operations are those subprograms associated with a type + +.. code:: Ada + + type Integer_T is range -(2**63) .. 2**63-1 with Size => 64; + procedure Increment_With_Truncation (Val : in out Integer_T); + procedure Increment_With_Rounding (Val : in out Integer_T); + +* Most types have some primitive operations defined by the language + + * e.g. equality operators for most types, numeric operators for integers and floats + +* A primitive operation on the parent can receive an object of a child type with no conversion + + .. code:: Ada + + declare + N_Obj : Natural_T := 1234; + begin + Increment_With_Truncation (N_Obj); + end; + +--------------------------------------- +General Rule for Defining a Primitive +--------------------------------------- + +* Primitives are subprograms +* Subprogram :ada:`S` is a primitive of type :ada:`T` if and only if: + + - :ada:`S` is declared in the scope of :ada:`T` + - :ada:`S` uses type :ada:`T` + + + As a parameter + + As its return type (for a :ada:`function`) + + - :ada:`S` is above :dfn:`freeze-point` (see next section) + +* Standard practice + + - Primitives should be declared **right after** the type itself + - In a scope, declare at most a **single** type with primitives + + .. code:: Ada + + package P is + type T is range 1 .. 10; + procedure P1 (V : T); + procedure P2 (V1 : Integer; V2 : T); + function F return T; + end P; + +------------------------------ +Primitive of Multiple Types +------------------------------ + +A subprogram can be a primitive of several types + + .. code:: Ada + + package P is + type Distance_T is range 0 .. 9999; + type Percentage_T is digits 2 range 0.0 .. 1.0; + type Units_T is (Meters, Feet, Furlongs); + + procedure Convert (Value : in out Distance_T; + Source : Units_T; + Result : Units_T; + procedure Shrink (Value : in out Distance_T; + Percent : Percentage_T); + + end P; + +* :ada:`Convert` and :ada:`Shrink` are primitives for :ada:`Distance_T` +* :ada:`Convert` is also a primitive of :ada:`Units_T` +* :ada:`Shrink` is also a primitive of :ada:`Percentage_T` + +---------------------------------- +Creating Primitives for Children +---------------------------------- + +* Just because we can inherit a primitive from out parent doesn't mean we want to + +* We can create a new primitive (with the same name as the parent) for the child + + * Very similar to overloaded subprograms + * But added benefit of visibility to grandchildren + +* We can also remove a primitive (see next slide) + +.. code:: Ada + + type Integer_T is range -(2**63) .. 2**63-1; + procedure Increment_With_Truncation (Val : in out Integer_T); + procedure Increment_With_Rounding (Val : in out Integer_T); + + type Child_T is new Integer_T range -1000 .. 1000; + procedure Increment_With_Truncation (Val : in out Child_T); + + type Grandchild_T is new Child_T range -100 .. 100; + procedure Increment_With_Rounding (Val : in out Grandchild_T); + +------------------------ +Overriding Indications +------------------------ + +* **Optional** indications +* Checked by compiler + + .. container:: latex_environment footnotesize + + .. code:: Ada + + type Child_T is new Integer_T range -1000 .. 1000; + procedure Increment_With_Truncation + (Val : in out Child_T); + procedure Just_For_Child + (Val : in out Child_T); + +* **Replacing** a primitive: :ada:`overriding` indication + + .. container:: latex_environment footnotesize + + .. code:: Ada + + overriding procedure Increment_With_Truncation + (Val : in out Child_T); + +* **Adding** a primitive: :ada:`not overriding` indication + + .. container:: latex_environment footnotesize + + .. code:: Ada + + not overriding procedure Just_For_Child + (Val : in out Child_T); + +* **Removing** a primitive: :ada:`overriding` as :ada:`abstract` + + .. container:: latex_environment footnotesize + + .. code:: Ada + + overriding procedure Just_For_Child + (Val : in out Grandchild_T) is abstract; + +* Using :ada:`overriding` or :ada:`not overriding` incorrectly will generate a compile error + +.. + language_version 2005 + +------ +Quiz +------ + +.. include:: ../quiz/operators_override_simple/quiz.rst diff --git a/courses/fundamentals_of_ada/075_type_derivation/04-freeze_point.rst b/courses/fundamentals_of_ada/075_type_derivation/04-freeze_point.rst new file mode 100644 index 000000000..afbba5746 --- /dev/null +++ b/courses/fundamentals_of_ada/075_type_derivation/04-freeze_point.rst @@ -0,0 +1,117 @@ +============== +Freeze Point +============== + +----------------------------- +What is the "Freeze Point"? +----------------------------- + +* Ada doesn't explicitly identify the end of the "scope" of a type + + * The compiler needs to know it for determining primitive operations + * Also needed for other situations (described elsewhere) + +* This end is the implicit **freeze point** occurring whenever: + + - A **variable** of the type is **declared** + - The type is **derived** + - The **end of the scope** is reached + +* Subprograms past this "freeze point" are not primitive operations + +.. code:: Ada + + type Parent is Integer; + procedure Prim (V : Parent); + + type Child is new Parent; + + -- Parent has been derived, so it is frozen. + -- Prim2 is not a primitive + procedure Prim2 (V : Parent); + + V : Child; + + -- Child used in an object declaration, so it is frozen + -- Prim3 is not a primitive + procedure Prim3 (V : Child); + +----------------------- +Debugging Type Freeze +----------------------- + +* Freeze |rightarrow| Type **completely** defined +* Compiler does **need** to determine the freeze point + + - To instantiate, derive, get info on the type (:ada:`'Size`)... + - Freeze rules are a guide to place it + - Actual choice is more technical + + + May contradict the standard + +* :command:`-gnatDG` to get **expanded** source + + - **Pseudo-Ada** debug information + +:filename:`pkg.ads` + + .. code:: Ada + + type Up_To_Eleven is range 0 .. 11; + +:filename:`/pkg.ads.dg` + +.. container:: latex_environment tiny + + :: + + type example__up_to_eleven_t is range 0 .. 11; -- type declaration + [type example__Tup_to_eleven_tB is new short_short_integer] -- representation + freeze example__Tup_to_eleven_tB [] -- freeze representation + freeze example__up_to_eleven_t [] -- freeze representation + +------ +Quiz +------ + +.. container:: latex_environment tiny + + .. code:: Ada + + type Parent is range 1 .. 100; + procedure Proc_A (X : in out Parent); + + type Child is new Parent range 2 .. 99; + procedure Proc_B (X : in out Parent); + procedure Proc_B (X : in out Child); + + -- Other scope + procedure Proc_C (X : in out Child); + + type Grandchild is new Child range 3 .. 98; + + procedure Proc_C (X : in out Grandchild); + +.. container:: columns + + .. container:: column + + Which are :ada:`Parent`'s primitives? + + A. :answermono:`Proc_A` + B. ``Proc_B`` + C. ``Proc_C`` + D. No primitives of :ada:`Parent` + + .. container:: column + + .. container:: animate + + Explanations + + A. Correct + B. Freeze: :ada:`Parent` has been derived + C. Freeze: scope change + D. Incorrect + + diff --git a/courses/fundamentals_of_ada/075_type_derivation/99-summary.rst b/courses/fundamentals_of_ada/075_type_derivation/99-summary.rst new file mode 100644 index 000000000..fa3dbcd58 --- /dev/null +++ b/courses/fundamentals_of_ada/075_type_derivation/99-summary.rst @@ -0,0 +1,21 @@ +========= +Summary +========= + +--------- +Summary +--------- + +* :dfn:`Primitive` of a type + + - Subprogram above **freeze-point** that takes or returns the type + - Can be a primitive for **multiple types** + +* Freeze point rules can be tricky +* Simple type derivation + + - Types derived from other types can only **add limitations** + + + Constraints, ranges + + Cannot change underlying structure + diff --git a/courses/fundamentals_of_ada/adv_075_primitives.rst b/courses/fundamentals_of_ada/adv_075_primitives.rst deleted file mode 100644 index ad3579dee..000000000 --- a/courses/fundamentals_of_ada/adv_075_primitives.rst +++ /dev/null @@ -1,282 +0,0 @@ -********************* -Advanced Primitives -********************* - -.. container:: PRELUDE BEGIN - -.. container:: PRELUDE ROLES - -.. role:: ada(code) - :language: Ada - -.. role:: C(code) - :language: C - -.. role:: cpp(code) - :language: C++ - -.. container:: PRELUDE SYMBOLS - -.. |rightarrow| replace:: :math:`\rightarrow` -.. |forall| replace:: :math:`\forall` -.. |exists| replace:: :math:`\exists` -.. |equivalent| replace:: :math:`\iff` -.. |le| replace:: :math:`\le` -.. |ge| replace:: :math:`\ge` -.. |lt| replace:: :math:`<` -.. |gt| replace:: :math:`>` -.. |checkmark| replace:: :math:`\checkmark` - -.. container:: PRELUDE REQUIRES - -.. container:: PRELUDE PROVIDES - -.. container:: PRELUDE END - -============ -Primitives -============ - --------------- -Freeze Point --------------- - -* Ada doesn't explicitly identify the end of members declaration -* This end is the implicit **freeze point** occurring whenever: - - - A **variable** of the type is **declared** - - The type is **derived** - - The **end of the scope** is reached - -* Subprograms past this point are not primitive - -.. code:: Ada - - type Root is Integer; - procedure Prim (V : Root); - type Child is new Root; -- freeze root - procedure Prim2 (V : Root); -- Not a primitive - - V : Child; -- freeze child - procedure Prim3 (V : Child); -- Not a primitive - -------------------- -Debug Type Freeze -------------------- - -* Freeze |rightarrow| Type **completely** defined -* Compiler do **need** that point - - - To instantiate, derive, get info on the type (:ada:`'Size`)... - - Freeze rules are a guide to place it - - Actual choice is more technical - - + May contradict the standard - -* :command:`-gnatDG` to get **expanded** source - - - **Pseudo-Ada** debug information - -:filename:`pkg.ads` - -.. code:: Ada - - type Up_To_Eleven is range 0 .. 11; - -:filename:`/pkg.ads.dg` - -.. code:: Ada - - -- type declaration - type pkg__up_to_eleven is range 0 .. 11; - -- representation - [type pkg__Tup_to_elevenB is new short_short_integer] - -- freeze representation - freeze pkg__Tup_to_elevenB [] - -- freeze type - freeze pkg__up_to_eleven [] - -================= -Type Derivation -================= - ------------------------------- -Primitive of Multiple Types ------------------------------- - -* A subprogram can be a primitive of several types - - .. code:: Ada - - package P is - type T1 is range 1 .. 10; - type T2 is (A, B, C); - - procedure Proc (V1 : T1; V2 : T2); - function "+" (V1 : T1; V2 : T2) return T1; - end P; - -------------------------------- -Implicit Primitive Operations -------------------------------- - -* Type declaration implicitly creates primitives - - - Numerical and logical operations - - Code can overload or remove them - - .. code:: Ada - - package P is - type T1 is range 1 .. 10; - -- implicit - -- function "+" (Left, Right : T1) return T1; - end P; - ... - procedure Main is - V1, V2 : T1; - begin - V1 := V1 + V2; - end Main; - -------------------------- -Type Derivation: Review -------------------------- - -* For all types - - + Freeze point rules don't change - + Primitives are inherited by child types - + Conversion from child to parent possible - + Pre-defined set of primitives - - - ``"+", "-" ...`` for numeric types - - Comparison operators - - Equality except if :ada:`limited` - -* Derived types that are **not** :ada:`tagged` - - + Are **not** OOP - + Can remove a primitive - + Can declare a primitive of multiple types - + Can be converted from parent to child - - - Their representation does not change - - Could raise :ada:`Constraint_Error` (:ada:`range`...) - ------- -Quiz ------- - -.. include:: quiz/operators_override_simple/quiz.rst - ------- -Quiz ------- - -.. include:: quiz/derivation_op_override/quiz.rst - -==================== -Tagged Inheritance -==================== - ---------------------------------- -Liskov's Substitution Principle ---------------------------------- - -* :dfn:`LSP` is an object-oriented rule - - + Not imposed - - - But fits nicely with Ada's OOP design - - + Avoids numerous issues - + Can be verified by tools eg. :toolname:`GNAT Static Analysis Suite (GNAT SAS)` - -* *Objects of a parent type shall be replaceable by objects of its child types* - - + Cannot be applied to simple derivation (eg. restricting range) - + Tagged record derivation implies **extending** not modifying the behaviour - - - Easier said than done - - *Is a mute cat still a cat if it can't meow?* - -------------- -Dispatching -------------- - -* Primitives dispatch, but not only them - -.. include:: examples/adv_075_primitives/dispatching.1.rst - -* :ada:`Prim` is a primitive -* :ada:`Not_Prim` is **not** a primitive - - + Won't be inherited - + But dispatches dynamically! - -.. include:: examples/adv_075_primitives/dispatching.2.rst - ------------------------------- -Tagged Primitive Declaration ------------------------------- - -* :ada:`tagged` types primitives **must** be declared in a :ada:`package` specification -* Not a :ada:`declare` block or the declarative part of a subprogram - -.. include:: examples/adv_075_primitives/subprogram_primitive_declaration.rst - :code: Ada - ------------------------------ -Primitive of Multiple Types ------------------------------ - -* For a primitive of a :ada:`tagged record Tag_T` - - - :ada:`Tag_T` is called the :dfn:`controlling parameter` - - All controlling parameters **must** be of the same type - -* Warning: A non-tagged type is never controlling - - - Can have primitive of multiple :ada:`type` - - **Cannot** have primitive of multiple :ada:`tagged record` - -.. code:: Ada - - type Root1 is tagged null record; - type Root2 is tagged null record; - - procedure P1_Correct (V1 : Root1; V2 : Root1); - procedure P2_Incorrect (V1 : Root1; V2 : Root2); -- FAIL - ----------------------------- -Tagged Inheritance: Review ----------------------------- - -* :ada:`tagged` types are Ada's OOP -* They can - - + Be converted from child to parent: :ada:`Parent_Type (Child)` - - - :dfn:`Upcast` in OOP parlance - -* They **cannot** - - + Remove a primitive - + Have a primitive with multiple controlling types - + Be converted from parent to child: :ada:`Child_Type (Parent)` - - - Because their representation may change - - :dfn:`Downcast` forbidden in OOP parlance - ------- -Quiz ------- - -.. include:: quiz/multiple_primitive/quiz.rst - ------- -Quiz ------- - -.. include:: quiz/primitives_and_classwide/quiz.rst diff --git a/courses/fundamentals_of_ada/advanced.txt b/courses/fundamentals_of_ada/advanced.txt index 40dbda808..3b61c929b 100644 --- a/courses/fundamentals_of_ada/advanced.txt +++ b/courses/fundamentals_of_ada/advanced.txt @@ -2,7 +2,6 @@ 030_basic_types-extras.rst 060_record_types.rst 065_discriminated_records.rst -adv_075_primitives.rst 080_expressions-with_quantified.rst 120_limited_types.rst adv_120_advanced_privacy.rst