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=3.1 required=5.0 tests=BAYES_20,FROM_WORDY, INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,772ae8afc5db35f2 X-Google-Attributes: gid103376,public From: "Nick Roberts" Subject: Single Extension; Polymorphic Arrays Date: 1999/03/03 Message-ID: <7bju1u$q23$1@plug.news.pipex.net>#1/1 X-Deja-AN: 450831748 References: X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 Organization: UUNET WorldCom server (post doesn't reflect views of UUNET WorldCom) Newsgroups: comp.lang.ada Date: 1999-03-03T00:00:00+00:00 List-Id: It dawns on me that Ada provides special syntax for singletons of two particular kinds of types: tasks and protected objects. Perhaps it would not be too drastic to provide for singletons of tagged types? Given a base type: type Pop_Star is [abstract] tagged ...; with an operation such as: procedure Exploit (Star: in [out] Pop_Star; Creaming_Off: out Money) [is abstract]; we might allow a 'single extension declaration': Elvis: [aliased] [constant] new Pop_Star with record ... end record; or a 'single private extension declaration': Elvis: [aliased] [constant] new Pop_Star with private; which would then have to be privately completed by a full single extension. The object 'Elvis' would be of an anonymous tagged type. It would not be possible to derive from this anonymous type, because it could not be named. The Tag attribute would be applicable to an object such as 'Elvis', but not the Class attribute. The 'in' operation would be applicable to such objects (but probably not often used). A 'single-object' parameter form could be used within subprogram declarations: procedure Exploit (for [constant] Elvis; Creaming_Off: out Money); The 'constant' would be required for an 'in' parameter, and omitted for an 'out', 'in out', or 'access' parameter. These subprograms would be primitive operations of the anonymous type of the object 'Elvis' (if declared within the same package specification). A totally separate, but also useful idea, it occurs to me, would be 'polymorphic arrays': arrays which have an indefinite component subtype. Supposing we extended the Pop_Star hierarchy: type Singer is new Pop_Star with ...; type Violinist is new Pop_Star with ...; type Drummer is new Pop_Star with ...; type Guitarist is new Pop_Star with ...; We could then use an array object declaration to create an array of objects of different, but related, types: type Corr_Name is (Andrea, Sharon, Caroline, Jim); Corrs: [aliased] [constant] array (Corr_Name) of Pop_Star'Class (Singer, Violinist, Drummer, Guitarist); At the end of this declaration is a new piece of syntax: the 'polymorphic array type association'. This is like an aggregate (and allows named associations like an aggregate), but only specifies types (which must all be definite). Once the types of the components of one of these arrays are set, they cannot be changed (i.e. the array is permanently constrained). Alternatively, an initialisation can be used specify the different types of the components: Corrs: [aliased] [constant] array (Corr_Name) of Pop_Star'Class := (Andrea => (Singer with ...), Sharon => (Violinist with ...), Caroline => (Drummer with ...), Jim => (Guitarist with ...)); This demonstrates a new form of array aggregate -- a 'polymorphic array aggregate' -- that could never be legal in Ada at present. As usual, an initialisation could be used in addition to a type association, in which case the types must all match. A named polymorphic array type could be declared: type Pop_Group is array (Positive range <>) of [aliased] Pop_Star'Class; and then objects of this type could be declared, e.g.: Spice_Girls: Pop_Group(1..4)(others => Singer); Metallica: Pop_Group := (1 => (Singer with ...), 2|3 => (Guitarist with ...), 4 => (Drummer with ...)); and the usual operations would then be available: Brian_Adams: Singer; Super_7: Pop_Group(1..7) := Spice_Girls(2..3) & Metallica & Brian_Adams; Implementation of these types would be a cinch (probably just an array of pointers plus a block of data), and they would be terrifically useful. A classic example is the 'sparse array' (one which has more holes in it than you would care to waste memory on). Another is the 'array of strings', e.g.: Messages: constant array (1..100) of String := (1 => "Error: you must put the milk in before the tea", 2 => "Error: you must extend your little finger when holding the cup", ...); Doing the equivalent of this in Ada 95 is still a pain. More ideas for Ada 200X? (Yet more :-) ------------------------------------- Nick Roberts -------------------------------------