• Aggregate with derived types.

    From Blady@21:1/5 to All on Thu Sep 14 16:02:39 2023
    Hello,

    I want to extend a container type like Vectors, I've written:
    type My_Float_List2 is new My_Float_Lists.Vector with null record;

    But the initialization gives an error line 6:

    1. with Ada.Containers.Vectors;
    2. with Ada.Text_IO;
    3. procedure test_20230914_derived_agg is
    4. package My_Float_Lists is new Ada.Containers.Vectors
    (Positive, Float);
    5. subtype My_Float_List1 is My_Float_Lists.Vector;
    6. type My_Float_List2 is new My_Float_Lists.Vector with null
    record;
    7. ML1 : My_Float_List1 := [-3.1, -6.7, 3.3, -3.14, 0.0];
    8. ML2 : My_Float_List2 := ([-3.1, -6.7, 3.3, -3.14, 0.0] with
    null record);
    |
    >>> error: no unique type for this aggregate
    9. begin
    10. Ada.Text_IO.Put_Line (ML1.Element (3)'Image);
    11. Ada.Text_IO.Put_Line (ML2.Element (3)'Image);
    12. end test_20230914_derived_agg;

    The RM says:
    4.3.2 Extension Aggregates
    1 [An extension_aggregate specifies a value for a type that is a record extension by specifying a value or subtype for an ancestor of the type, followed by associations for any components not determined by the ancestor_part.]
    Language Design Principles
    1.a The model underlying this syntax is that a record extension can
    also be viewed as a regular record type with an ancestor
    "prefix".
    The record_component_association_list corresponds to
    exactly what
    would be needed if there were no ancestor/prefix type. The
    ancestor_part determines the value of the ancestor/prefix.
    Syntax
    2 extension_aggregate ::=
    (ancestor_part with record_component_association_list)
    3 ancestor_part ::= expression | subtype_mark

    It is not so clear for me what could a unique type?
    Any clue?

    Thanks Pascal.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeffrey R.Carter@21:1/5 to Blady on Thu Sep 14 17:31:47 2023
    On 2023-09-14 16:02, Blady wrote:

         1. with Ada.Containers.Vectors;
         2. with Ada.Text_IO;
         3. procedure test_20230914_derived_agg is
         4.    package My_Float_Lists is new Ada.Containers.Vectors (Positive, Float);
         5.    subtype My_Float_List1 is My_Float_Lists.Vector;
         6.    type My_Float_List2 is new My_Float_Lists.Vector with null record;
         7.    ML1 : My_Float_List1 := [-3.1, -6.7, 3.3, -3.14, 0.0];
         8.    ML2 : My_Float_List2 := ([-3.1, -6.7, 3.3, -3.14, 0.0] with null
    record);
                                        |
            >>> error: no unique type for this aggregate

    IIUC, you have to qualify the value:

    (My_Float_List1'[-3.1, -6.7, 3.3, -3.14, 0.0] with null record)

    or

    (My_Float_Lists.Vector'[-3.1, -6.7, 3.3, -3.14, 0.0] with null record)

    (not tested)

    --
    Jeff Carter
    "[M]any were collected near them, ... to
    enjoy the sight of a dead young lady, nay,
    two dead young ladies, for it proved twice
    as fine as the first report."
    Persuasion
    155

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Blady@21:1/5 to All on Thu Sep 14 22:00:19 2023
    Le 14/09/2023 à 17:31, Jeffrey R.Carter a écrit :
    On 2023-09-14 16:02, Blady wrote:

          1. with Ada.Containers.Vectors;
          2. with Ada.Text_IO;
          3. procedure test_20230914_derived_agg is
          4.    package My_Float_Lists is new Ada.Containers.Vectors
    (Positive, Float);
          5.    subtype My_Float_List1 is My_Float_Lists.Vector;
          6.    type My_Float_List2 is new My_Float_Lists.Vector with null
    record;
          7.    ML1 : My_Float_List1 := [-3.1, -6.7, 3.3, -3.14, 0.0]; >>       8.    ML2 : My_Float_List2 := ([-3.1, -6.7, 3.3, -3.14, 0.0] >> with null record);
                                         | >>          >>> error: no unique type for this aggregate

    IIUC, you have to qualify the value:

    (My_Float_List1'[-3.1, -6.7, 3.3, -3.14, 0.0] with null record)

    or

    (My_Float_Lists.Vector'[-3.1, -6.7, 3.3, -3.14, 0.0] with null record)

    (not tested)

    Thanks Jeff, both proposals are compiled ok by GNAT.

    I wonder why the float list aggregate isn't inferred by the compiler and
    need some help with a qualification.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeffrey R.Carter@21:1/5 to Blady on Thu Sep 14 23:37:47 2023
    On 2023-09-14 22:00, Blady wrote:

    I wonder why the float list aggregate isn't inferred by the compiler and need some help with a qualification.

    I'm not sure. But can't you simply write

    ML2 : My_Float_List2 := [-3.1, -6.7, 3.3, -3.14, 0.0];

    ? I presume that My_Float_List2 inherits its aggregate definition from My_Float_List1.

    --
    Jeff Carter
    "[M]any were collected near them, ... to
    enjoy the sight of a dead young lady, nay,
    two dead young ladies, for it proved twice
    as fine as the first report."
    Persuasion
    155

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Blady@21:1/5 to All on Fri Sep 15 09:27:57 2023
    Le 14/09/2023 à 23:37, Jeffrey R.Carter a écrit :
    On 2023-09-14 22:00, Blady wrote:

    I wonder why the float list aggregate isn't inferred by the compiler
    and need some help with a qualification.

    I'm not sure. But can't you simply write

    ML2 : My_Float_List2 := [-3.1, -6.7, 3.3, -3.14, 0.0];

    ? I presume that My_Float_List2 inherits its aggregate definition from My_Float_List1.

    Unfortunately not directly:
    10. ML2c : My_Float_List2 := [-3.1, -6.7, 3.3, -3.14, 0.0];
    |
    >>> error: type of aggregate has private ancestor "Vector"
    >>> error: must use extension aggregate

    Shouldn't inherit them?

    Indeed you have it if you defined a private extension with explicit aspects:
    package PA is
    type My_Float_List3 is new My_Float_Lists.Vector with private with
    Constant_Indexing => Constant_Reference,
    Variable_Indexing => Reference,
    Default_Iterator => Iterate,
    Iterator_Element => Float,
    Aggregate =>
    (Empty => Empty, Add_Unnamed => Append, New_Indexed =>
    New_Vector, Assign_Indexed => Replace_Element);
    function Constant_Reference
    (Container : aliased My_Float_List3; Index : Positive) return My_Float_Lists.Constant_Reference_Type is
    (My_Float_Lists.Constant_Reference (My_Float_Lists.Vector
    (Container), Index));
    function Reference (Container : aliased in out My_Float_List3;
    Index : Positive) return My_Float_Lists.Reference_Type is
    (My_Float_Lists.Reference (My_Float_Lists.Vector (Container),
    Index));
    private
    type My_Float_List3 is new My_Float_Lists.Vector with null record;
    end PA;

    ML3 : PA.My_Float_List3 := [-3.1, -6.7, 3.3, -3.14, 0.0];

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Randy Brukardt@21:1/5 to Blady on Sat Sep 16 01:39:57 2023
    "Blady" <p.p11@orange.fr> wrote in message
    news:udvooj$2oveh$1@dont-email.me...
    ...
    I wonder why the float list aggregate isn't inferred by the compiler and
    need some help with a qualification.

    The language rule is that the ancestor_part of an extension aggregate is expected to be of "any tagged type" (see 4.3.2(4/2)). An aggregate needs to have a single specific type, and "any tagged type" is not that.

    The reason that the ancestor is "any tagged type" is that the type of the ancestor determines the extension components needed along with other
    legality rules. One could imagine a language where all of these things are decided simulateously, but people worried that the complexity would make it difficult/impossible to implement. So aggregates are essentially black boxes whose type has to be determinable from the outside, and similar rules exist
    for parts inside the aggregate.

    Randy.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)