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=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,bd40601768eaf8fd X-Google-Attributes: gid103376,public From: "Nick Roberts" Subject: Re: Array of Variant Records Question... Date: 1999/09/10 Message-ID: <37d8486c@eeyore.callnetuk.com> X-Deja-AN: 523169173 References: <7r5vh3$imu1@svlss.lmms.lmco.com> <37d6a45c@news1.prserv.net> <37d74dea@eeyore.callnetuk.com> <37D7B099.8C1A5CC6@averstar.com> X-Original-NNTP-Posting-Host: da133d10.dialup.callnetuk.com X-Trace: 10 Sep 1999 00:53:16 GMT, da133d10.dialup.callnetuk.com X-MSMail-Priority: Normal X-Priority: 3 Newsgroups: comp.lang.ada X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 Date: 1999-09-10T00:00:00+00:00 List-Id: Please find below an article I posted on comp.lang.ada in March this year. Please forgive the length of it. ------------------------------------- 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 :-) ------------------------------------- When I suggest an implementation of an array of pointers and a block of data, I think both Tucker and Robert Dewar misunderstand: I don't intend the data - either in a block or individually - to be allocated on the heap (unless the whole array is). They can both be allocated in the same place (the stack for variables, constant data space for constants, or wherever). This is because the polymorphic array type that I suggest is always either completely unconstrained or completely constrained: when it's constrained, the size of both the array of pointers and the block of data of an object of the type is known and fixed; when it's unconstrained, an object of the type cannot be declared. Simple, straightforward, and efficient. I would be interested in making this a formal proposal for the next revision of Ada (if someone would be kind enough to tell me how :-), together with the singleton tagged type as well. I would appreciate help! Tucker says this idea "does not seem to be providing significant new capability that cannot be programmed already using existing features." I disagree. I think it's a feature that would be extremely useful, and not just a nicety. Consider the constant array of strings example. Best wishes, ------------------------------------- Nick Roberts http://www.adapower.com/lab/adaos ------------------------------------- Tucker Taft wrote in message news:37D7B099.8C1A5CC6@averstar.com... | Nick Roberts wrote: | > | > The flaw is that Ada has no 'polymorphic array type': an array that has an | > indefinite component subtype. | > | > As I suggested in a post a few months ago, such an array type would be easy | > to add to Ada's existing syntax, easy and efficient to implement (as an | > array of pointers plus a ragged sequence of objects, internally), and very | > bloody useful, pardon the language. (It would have solved Bruce's problem in | > a trice.) | | We considered full support for "indefinite"/unconstrained subtypes | during the Ada 9X process, but ultimately decided to avoid any | language feature that would require implicit levels of indirection | within an object. The general philosophy here is that levels of indirection | should be under the control of the programmer, not the compiler. | You can certainly create a structure much like what you propose by | an array of pointers, initialized with a sequence of allocators. | The benefits from building such a capability into the language | itself would probably not justify the added complexity, particularly | when you consider the fine level of representation control Ada programmers | desire over data structures. | | > | > Maybe come the next review... | | If you have a detailed proposal with examples, ACVC tests, etc., feel free | to document it. However, don't hold your breath for this to happen, | since (at least as far as I understand it) does not seem to be providing | significant new capability that cannot be programmed already using | existing features.