@@ -530,6 +530,8 @@ view because it's a private type. Finally, as expected, :ada:`Settings` has a
530530variable view because it's a variable object.
531531
532532
533+ .. _Adv_Ada_Named_Numbers :
534+
533535Named numbers
534536~~~~~~~~~~~~~
535537
@@ -557,18 +559,21 @@ A named number is always known at compilation time. Also, it doesn't have a
557559type associated with it. In fact, its type is called universal real or
558560universal integer |mdash | depending on the number being a real or integer
559561number. (In this specific case, :ada: `Pi ` is a universal real number.) We talk
560- about universal real and universal integer types in another chapter.
562+ about :ref: `universal types <Adv_Ada_Universal_Types >` later on in this
563+ chapter.
561564
562565.. todo ::
563566
564- Add link to section on universal real and universal integer types
565- (Adv_Ada_Universal_Real_Integer ) once it's available.
567+ Add link to section on universal real, integer and fixed types
568+ (Adv_Ada_Universal_Real_Integer_Fixed ) once it's available.
566569
567570.. admonition :: In the Ada Reference Manual
568571
569572 - :arm22: `3.3.2 Number Declarations <3-3-2> `
570573
571574
575+ .. _Adv_Ada_Scalar_Types :
576+
572577Scalar Types
573578------------
574579
@@ -1483,6 +1488,185 @@ representation clause. We discuss this topic
14831488:ref: `in another section <Adv_Ada_Enumeration_Representation_Clauses >`.
14841489
14851490
1491+ .. _Adv_Ada_Universal_And_Root_Types :
1492+
1493+ Universal and Root Types
1494+ ------------------------
1495+
1496+ Previously, in the section about :ref: `scalar types <Adv_Ada_Scalar_Types >`,
1497+ we said that scalar types are the most basic types that we can get. However,
1498+ Ada has the concept of universal and root types, which could be
1499+ considered *more basic * than scalar types. In fact, universal and root types
1500+ are underlying scalar types used by the language designers to define the
1501+ language semantics. In this section, we briefly introduce this topic.
1502+
1503+ .. _Adv_Ada_Universal_Types :
1504+
1505+ Universal Types
1506+ ~~~~~~~~~~~~~~~
1507+
1508+ The Ada standard defines four universal types:
1509+
1510+ #. universal integer types
1511+
1512+ #. universal real types
1513+
1514+ #. universal fixed types
1515+
1516+ #. universal access types
1517+
1518+ The first three are numeric types, and we discuss them in detail later on
1519+ in another chapter. The last one
1520+ is used for :ref: `anonymous access types <Adv_Ada_Anonymous_Access_Types >`.
1521+
1522+ .. todo ::
1523+
1524+ Add link to section on universal real, integer and fixed types
1525+ (Adv_Ada_Universal_Real_Integer_Fixed) once it's available.
1526+
1527+ .. todo ::
1528+
1529+ Add link to section on universal access types once it's available.
1530+
1531+ Universal types aren't types we can use directly, but rather via specific
1532+ languages constructs. In this sense, we cannot derive from universal types, but
1533+ only make use of them indirectly.
1534+
1535+ For instance, if we declare :ref: `named numbers <Adv_Ada_Named_Numbers >` using
1536+ a real value, we're indirectly using a universal real type. If we declare
1537+ another named number using an expression, the computation is performed based on
1538+ the universal types of the elements of that expression:
1539+
1540+ .. code :: ada compile_button project=Courses.Advanced_Ada.Data_Types.Types.Universal_And_Root_Types.Universal_Real_Integer
1541+
1542+ package Show_Universal_Real_Integer is
1543+
1544+ Pi : constant := 3.1415926535;
1545+ -- ^^^^^^^^^^^^
1546+ -- universal real type
1547+
1548+ Two_Pi : constant := Pi * 2.0;
1549+ -- ^^^^^^^^
1550+ -- operation on
1551+ -- universal real type
1552+
1553+ N : constant := 10;
1554+ -- ^^
1555+ -- universal integer type
1556+
1557+ N_10 : constant := N * 10;
1558+ -- ^^^^^^
1559+ -- operation on
1560+ -- universal integer type
1561+
1562+ end Show_Universal_Real_Integer;
1563+
1564+ In this example, the expression :ada: `Pi * 2.0 ` is computed using universal
1565+ real types, while the expression :ada: `N * 10 ` is computed using universal
1566+ integer types.
1567+
1568+ Similarly, for anonymous access types, the equality operator uses universal
1569+ access types for the comparison:
1570+
1571+ .. code :: ada run_button project=Courses.Advanced_Ada.Data_Types.Types.Universal_And_Root_Types.Universal_Access
1572+
1573+ with Ada.Text_IO; use Ada.Text_IO;
1574+
1575+ procedure Show_Universal_Access is
1576+ I : aliased Integer;
1577+ A : access Integer := I'Access;
1578+ B : access Integer := I'Access;
1579+ begin
1580+ if A = B then
1581+ Put_Line ("A = B");
1582+ else
1583+ Put_Line ("A /= B");
1584+ end if;
1585+ end Show_Universal_Access;
1586+
1587+ In this example, both :ada: `A ` and :ada: `B ` are variables of anonymous access
1588+ types. Because the type isn't a known named type, the equality operation
1589+ :ada: `= ` uses the universal access type for the comparison.
1590+
1591+ .. admonition :: In the Ada Reference Manual
1592+
1593+ - :arm22: `3.3.2 Number Declarations <3-3-2> `
1594+ - :arm22: `4.5.2 Relational Operators and Membership Tests <4-5-2> `
1595+
1596+
1597+ .. _Adv_Ada_Root_Types :
1598+
1599+ Root Types
1600+ ~~~~~~~~~~
1601+
1602+ The root types can be found on a level above the universal types. In this
1603+ category, we can find the same numeric types that we have for universal types,
1604+ namely the root real, root integer and root fixed types.
1605+
1606+ The term *root * is used in the context of type derivation. In fact, the root
1607+ type is the first type that we derive all other types from. In other words, if
1608+ we declare an integer range as a new type, that type is derived from the root
1609+ integer type. Similarly, if we declare a new floating-point type, that type is
1610+ derived from the root real type. For example:
1611+
1612+ .. code :: ada compile_button project=Courses.Advanced_Ada.Data_Types.Types.Universal_And_Root_Types.Root_Integer_Real
1613+
1614+ package Show_Root_Integer_Real is
1615+
1616+ type Score is range 0 .. 10;
1617+ -- Type Score is derived from
1618+ -- the root integer type.
1619+
1620+ type Real_Score is
1621+ digits 10 range 0.0 .. 10.0;
1622+ -- Type Real_Score is derived from
1623+ -- the root real type.
1624+
1625+ end Show_Root_Integer_Real;
1626+
1627+ Here, :ada: `Score ` and :ada: `Real_Score ` are derived from the root integer and
1628+ real types, respectively. Note that the derivation is always implicit, as we
1629+ cannot write something like
1630+ :ada: `type Score is new Root_Integer range 0 .. 10 ` or
1631+ :ada: `type Real_Score is new Root_Real digits 10 range 0.0 .. 10.0 `.
1632+
1633+ In contrast, if we derive from an existing floating-point or integer type
1634+ defined by the Ada standard, we're not deriving directly from the root types:
1635+
1636+ .. code :: ada compile_button project=Courses.Advanced_Ada.Data_Types.Types.Universal_And_Root_Types.Standard_Integer_Float_Derivation
1637+
1638+ package Show_Standard_Derivation is
1639+
1640+ type Score is new Integer
1641+ range 0 .. 10;
1642+ -- Type Score is derived from
1643+ -- the Integer type.
1644+
1645+ type Real_Score is new Float
1646+ range 0.0 .. 10.0;
1647+ -- Type Real_Score is derived from
1648+ -- the Float type.
1649+
1650+ end Show_Standard_Derivation;
1651+
1652+ In this case, we're explicitly deriving from the standard Ada types
1653+ :ada: `Integer ` and :ada: `Float `, which, on their turn, are derived from the
1654+ root integer and root real types, respectively.
1655+
1656+ .. admonition :: For further reading...
1657+
1658+ You might remember our discussion about the
1659+ :ref: `Base attribute <Adv_Ada_Base_Attribute >` and the fact that it
1660+ indicates the underlying subtype of a type. We said, for example, that
1661+ :ada: `Integer'Base ` gives us the base type of :ada: `Integer `, i.e. the
1662+ the underlying hardware type representing the :ada: `Integer ` type.
1663+
1664+ Although the concept of the base type *sounds * similar to the concept of
1665+ the root type, the focus of each one is different: while the base type
1666+ refers to the constraints of a type, the root type refers to the derivation
1667+ tree of a type.
1668+
1669+
14861670.. _Adv_Ada_Definite_Indefinite_Subtypes :
14871671
14881672Definite and Indefinite Subtypes
0 commit comments