Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Aggregate with derived types.

53 views
Skip to first unread message

Blady

unread,
Sep 14, 2023, 10:02:44 AM9/14/23
to
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.


Jeffrey R.Carter

unread,
Sep 14, 2023, 11:31:51 AM9/14/23
to
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

Blady

unread,
Sep 14, 2023, 4:00:23 PM9/14/23
to
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.

Jeffrey R.Carter

unread,
Sep 14, 2023, 5:37:49 PM9/14/23
to
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.

Blady

unread,
Sep 15, 2023, 3:28:01 AM9/15/23
to
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];

Randy Brukardt

unread,
Sep 16, 2023, 2:39:39 AM9/16/23
to
"Blady" <p....@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.


0 new messages