comp.lang.ada
 help / color / mirror / Atom feed
* Proposal: Constructors, Assignment [LONG]
@ 2002-12-24 11:16 Dmitry A. Kazakov
  2002-12-26 22:11 ` Nick Roberts
  0 siblings, 1 reply; 20+ messages in thread
From: Dmitry A. Kazakov @ 2002-12-24 11:16 UTC (permalink / raw)


The proposal possibly solves the problems:

1. Constructors with parameters for all user types
2. Initialization of limited types
3. Assignments for all user types
4. Ability to do things like stream attributes
5. Expressions for discriminants hidden within a constructor

The general idea is to split constructor (and assignment) into two 
separate subroutines. One is used to get constraints, another is to 
finish construction. The subroutine for getting constraints returns them 
as an anonymous record type (an attribute is used to denote it) with the 
discriminants set to the constraints.

Example1:

type Socket (Host_Name_Length : Positive) is tagged limited
record
   Host_Name : String (1..Host_Name_Length);
   . . .; -- Other components
end record;
function Get_Constraint (Host_Name : String)
   return Socket'Constraint;
for Socket'Get_Constraints use Get_Constraint;
procedure Initialize (Object : in out Socket; Host_Name : String);
for Socket'Initialize use Initialize;

[ Maybe to prevent "syntactic sugar diabetes", we could allow to override 
these and all others subroutine attributes just like:
function Socket'Get_Constraints (Host_Name : String)
   return Socket'Constraint;
]
...
function Get_Constraint (Host_Name : String)
   return Socket'Constraint is
begin
   return (Host_Name => Host_Name'Length);
end Get_Constraint;
...
procedure Initialize
   (Object : in out Socket; Host_Name : String) is
begin
   Object.Name := Host_Name;
   Open_Connection (Host_Name);
end Initialize;
...
Connection : Socket ("127.0.0.1");

Example2:

type Char_String is array (Integer range <>) of Unsigned_8;
function Get_Bounds (Text : String)
   return Char_String'Constraints;
for Char_String'Get_Constraints use Get_Bounds;
procedure Set (Object : in out Char_String; Text : String);
for Char_String'Initialize use Set;
...
function Get_Bounds (Text : String)
   return Char_String'Constraints is
begin
   return (First_1 => 1, Last_1 => Text'Length);
end Get_Bounds;
...
procedure Set (Object : in out Char_String; Text : String) is
   To : Integer := Object'First;
begin
   for From  in Text'Range loop
      Object (To) := Unsigned_8 (Character'Pos (Text (From)));
   end loop;
end Set;
...
X : Char_String ("some text");  -- Constructor
Y : Char_String := "some text"; -- Assignment

More formal

1. Attribute S'Constraints.

For any subtype S there is an attribute S'Constraints, defined as an 
anonymous record type:

type S'Constraints [(<the-list-of-constraints>)] is null record;

[VARIANT for any tagged type]

1.1 For a constrained type <the-list-of-constraints> is empty.
1.2 For an unconstrained array type it is the array bounds (named in 
some nice way).
1.3 For an unconstrained discriminated record, task, protected type it is 
the discriminant part of the type.
1.4 For a class-wide type it is Tag.

For example:

type User (Name_Length : Positive) is tagged record
   Name : String (1..Name_Length);
   ID : User_ID;
end record;

User'Constraint is
   type * (Name_Length : Positive) is null record;

User'Class'Constraint is
   type * (Type_Tag : Tag) is null record;

2. Attribute S'Get_Constraints denotes a set of overloaded functions 
having the following parameter profiles:

function S'Get_Constraints [(<parameter-list>)]
   return S'Constraints;

2.1 For a constrained type:
   function S'Get_Constraints return S'Constraints;
is defined and returns null record;

2.2 For an unconstrained array type:
   function S'Get_Constraints (<bounds-list>)
      return S'Constraints;
is defined and returns S'Constraints with the discriminants set to the 
bounds from the list.

2.3 For an unconstrained discriminated type
   function S'Get_Constraints (<discriminant-list>)
      return S'Constraints;
is defined and returns S'Constraint with discriminants set from the 
list.

2.4. For a class-wide type it is not defined. It can be defined 
(S'Class'Get_Constraint), then S'Get_Constraints and S'Initialize have 
to be defined as well.

Additionally for non-limited types:
   function S'Get_Constraints (Source : S)
      return S'Constraints;
is defined and returns S'Constraints with the discriminants extracted 
from the constraints of Source

When a derived type overrides discriminants, it has to override 
S'Get_Constraints as well.

3. Attribute S'Initialize denotes a set of overloaded procedures:

procedure S'Initialize (Object : in out S [; (<parameter-list>)]);

4. Constructors

4.1 Specific types. A constructor is defined if a pair 
S'Get_Constraints, S'Initialize is defined such that they have 
conformant parameter lists, the first parameter of S'Initialize is not 
counted.

For a specific subtype S the constructor works as follows:

1. S'Get_Constraint is called to get all necessary constraints
2. Memory is allocated according to the constraints
3. S'Initialize is called to finish construction

4.2 Class-wide types. A constructor is defined if 
S'Class'Get_Constraints is defined (and thus S'Get_Constraints and 
S'Initialize are defined for all descendants of S). For a class-wide 
subtype S'Class the constructor works as follows:

1. S'Class'Get_Constraint is called to get tag
2. Dispatching call to S'Get_Constraint [to get the constraints]
3. Memory is allocated according to the constraints
4. Dispatching call to S'Initialize [to finish construction]

4.3 Any constructor of a subtype S can be used in:

Object_Of_S : S (<parameter-list>);
new S ((<parameter-list>);
subtype Subtype_Of_S is S ((<parameter-list>);

5. Assignment

A constructor of S with the parameter list consisting of single 
parameter [VARIANT having the type S] is called copy-constructor.
For a non-limited type for each copy-constructor an assignment
is generated:

5.1 Specific types

1. S'Get_Constraint (Source) is called to get new constraints
2. New constraints are checked against the constraints of Target
3. Target is finalized
4. Constraints are overridden
5. S'Initialize (Target, Source) is called

5.2 Class-wide types

1. S'Class'Get_Constraint (Source) is called to get new tag
2. The new tag is checked against Target'Tag
3. S'Get_Constraint (Source) is called to get new constraints

4. New constraints are checked against the constraints of Target
5. Target is finalized
6. Tag and constraints are overridden
7. S'Initialize (Target, Source) is called

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2003-01-04 12:53 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-24 11:16 Proposal: Constructors, Assignment [LONG] Dmitry A. Kazakov
2002-12-26 22:11 ` Nick Roberts
2002-12-27 17:43   ` Dmitry A. Kazakov
2002-12-27 20:17     ` Randy Brukardt
2002-12-29 13:43       ` Dmitry A. Kazakov
2002-12-29 18:45         ` Nick Roberts
2002-12-30 12:23           ` Dmitry A. Kazakov
2002-12-30 15:14             ` Robert A Duff
2002-12-31 13:02               ` Dmitry A. Kazakov
2003-01-01  0:28                 ` Randy Brukardt
2003-01-01 14:13                   ` Dmitry A. Kazakov
2003-01-02 19:44                     ` Randy Brukardt
2003-01-03 13:21                       ` Dmitry A. Kazakov
2003-01-03 19:29                         ` Randy Brukardt
2003-01-03 20:50                       ` Robert A Duff
2003-01-04 12:53                         ` Dmitry A. Kazakov
2003-01-01  0:54         ` Randy Brukardt
2003-01-01 14:13           ` Dmitry A. Kazakov
2003-01-02 19:36             ` Randy Brukardt
2003-01-03 13:20               ` Dmitry A. Kazakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox