From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,72c34c66b38e0e05,start X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2002-12-24 03:16:21 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!nntp.cs.ubc.ca!fu-berlin.de!uni-berlin.de!dialin-145-254-040-172.arcor-ip.NET!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Proposal: Constructors, Assignment [LONG] Date: Tue, 24 Dec 2002 12:16:38 +0100 Organization: At home Message-ID: Reply-To: mailbox@dmitry-kazakov.de NNTP-Posting-Host: dialin-145-254-040-172.arcor-ip.net (145.254.40.172) Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7Bit X-Trace: fu-berlin.de 1040728579 5928256 145.254.40.172 (16 [77047]) User-Agent: KNode/0.7.1 Xref: archiver1.google.com comp.lang.ada:32278 Date: 2002-12-24T12:16:38+01:00 List-Id: 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 [()] is null record; [VARIANT for any tagged type] 1.1 For a constrained type 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 [()] 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 () 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 () 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 [; ()]); 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 (); new S ((); subtype Subtype_Of_S is S ((); 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