Skip to content

Looser restrictions on container aggregates #157

@liampwll

Description

@liampwll

The name resolution rules in RM 4.3.5(7/5) through (9/5) currently restrict the Add_Named etc. aggregate procedures to exactly one procedure rather than allowing for overloaded procedures. This increases the difficulty of implementing maps that take multiple types as values (a map representing a JSON object for instance). I would like to propose that the "exactly one" restriction is removed and resolution is based on types, as it would be if the underlying procedure (or set of procedures) were to be called directly.

In addition to this, the name resolution rules in RM 4.3.5(22/5) states that "The expected type for a container_aggregate shall be a single type for which the Aggregate aspect has been specified" where container_aggregate is defined as follows in (13/5):

container_aggregate ::= 
    null_container_aggregate
  | positional_container_aggregate
  | named_container_aggregate

I would like to propose that this name resolution goes one level deeper so that the expected type is one of the 3 types in that union based on the expression. It appears that the 3 types can be disambiguated at a syntax level without any extra semantic analysis.

With these two changes it would be possible to define a package as follows:

package JSON is

   type JSON_Value is tagged private;
   type JSON_Object  is new JSON_Value with private with Aggregate => (Empty => Empty, Add_Named => Insert);
   type JSON_Array   is new JSON_Value with private with Aggregate => (Empty => Empty, Add_Unnamed => Insert);

   procedure Insert (O : in out JSON_Object; Key : String; Value : JSON_Object);
   procedure Insert (O : in out JSON_Object; Key : String; Value : JSON_Array);
   procedure Insert (O : in out JSON_Object; Key : String; Value : Integer);
   procedure Insert (O : in out JSON_Object; Key : String; Value : Float);
   procedure Insert (O : in out JSON_Object; Key : String; Value : String);

   --  ... etc.

end JSON;

which would allow for expression to cleanly represent JSON objects as ["A" => 1, "B" => [1, 2], "C" => ["a" => a]] or similar.

It is currently possible to get something close to this by placing *_Literal on JSON_Value and changing Insert to only accept JSON_Value'Class, but this has a messier package definition and a messier expression which would look something like this: ["A" => 1, "B" => JSON_Array'[1, 2], "C" => JSON_Object'["a" => a]]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Feature RequestA proposal for a new language feature or capability

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions