!standard 3.10 (01) 01-09-30 AI95-00230/02 !class amendment 00-04-13 !status work item 00-04-13 !status received 00-04-13 !priority Medium !difficulty Hard !subject Generalized use of anonymous access types !summary More general use of anonymous access types is proposed, to allow the flexibility of implicit conversion and run-time accessibility checking to be used in more contexts, including as components, stand-alone variables, and as return types. !problem This proposal attempts to resolve a problem encountered when creating Ada packages to use in interfacing with code written in languages like Java, and in using various common object-oriented programming paradigms. In Java and other OO languages, types that are references to a subclass are freely convertible to types that are references to a superclass. This implicit conversion, which is always safe, significantly reduces the need for explicit conversions when passing references as parameters. Because Ada has local access types, there needs to be a way to remember the accessibility level of the object designated by a reference across assignments, parameter passing, and function return. !proposal The "access_definition" syntactic category (see ai-231) is permitted in more places than just as formal parameters and discriminants. It is permitted in subtype declarations, constant declarations, and for function return types. The type associated with the subtype, constant, or function return is an anonymous access type, which permits implicit conversions from other access types with appropriately compatible designated subtypes (as defined by 4.6(13-17)). The accessibility level of an anonymous access type is determined at the time when the access_definition is elaborated. For a function return type, this happens at the time the function returns. For a subtype of an anonymous access type, the accessibility level is the level of the subtype declaration. For a constant declaration, the level is the same as the level of the type of the initial value. For a function return, the level is the same as the level of the type of the returned value, which must be shallower than the level of the execution of the function (for obvious reasons). There is a special predefined equality (and matching inequality) operator declared in package Standard which requires at least one of the parameters to be of an anonymous access type, and the other to be convertible to that anonymous access type. An anonymous access type uses the default storage pool associated with its accessibility level. If an anonymous access type is used as the parent in a derived type declaration, the derived type is a "normal" access type, without any implicit conversion from other access types. An anonymous access type may be passed to a generic when the formal is an access type or a private type. !wording (See proposal.) !example !discussion In an object-oriented program, it is desirable to be able to use any descendant of a root type in a context that only depends on the properties of the root type. This principle is sometimes called "substitutability." This is supported in Ada 95 by use of T'Class as a parameter type. However, access types are used heavily in object-oriented systems, because of the unknown size requirements when dealing with a type hierarchy. The parameter notation "access T'Class" supports access type substitutability, but only for parameters. Furthermore, it doesn't handle potentially null values. Finally, it cannot be used for record or array components (other than access discriminants). [Note that the "null value" problem is solved in AI-231. We will make no further mention of this problem, and simply presume the generalization of access_definition proposed in AI-231 is in effect.] Explicit access type conversions can be used to provide the desired substitutability, but scattering type conversions around muddies the waters, and makes it harder to find the few type conversions that are really "significant." This AI proposes to generalize the use of anonymous access types, as declared by an access_definition. It avoids any incompatibility issues by not changing the implicit conversion rules for existing named access types. This proposal grew out of a long discussion about the difficulties associated with a "with access type" mechanism (originally part of AI-00217). The problems encountered relate to issues such as "thin" versus "fat" access-to-array types, conventions associated with access types, access subtypes, etc. Furthermore, Erhard Ploedereder reported significant concerns among his students with the excessive numbers of explicit conversions required to use Ada 95. This happens when an actual parameter is of type access-to-T2'Class, and the formal parameter is of type access-to-T1'Class. This problem could be solved by allowing implicit conversion only to general access-to-classwide types. However, the current access-type conversion rules are based more on the general vs. pool-specific distinction. Also, the mutually-recursive type problem need not involve tagged types at all. It would seem unnatural to require the use of tagged and class-wide types just to get the implicit conversion on named general access types that is already available for all anonymous general access types. We have proposed to allow named subtypes of anonymous access types, which is admittedly a mind-bending concept. However, subtypes have exactly the right implicit convertibility semantics, which is not in general shared by types. So by using subtype declarations to introduce these, hopefully we are suggesting the implicit convertibility. [Note that a recent suggestion regarding the "incomplete type stub" is to actually call these "subtype stubs" for a similar reason.] In addition to allowing access_definitions in subtype declarations, we have also proposed to allow them in constant declarations and function returns. We considered broadening this to more contexts, but this began to require that accessibility was associated with individual values rather than types. That would be a pretty big change to the accessibility level model, and bigger than seemed necessary. In both of these contexts, we can define the elaboration of the access_definition construct to occur at the time when the one and only value is provided, and thereby carry the accessibliity level of the initializing value's type into the accessibliity level of the anonymous type. If we allowed access_definitions in variable declarations or updatable component declarations, we would have difficulty specifying the accessibliity level of the anonymous type. Furthermore, we would need to define how run-time accessibliity level is carried across assignments. By allowing named subtypes of anonymous access types, we effectively allow the declaration in any context of objects which support implicit conversion, including as stand-alone variables and record or array components. However, because the accessibliity level of a named subtype is determined by the level of the subtype declaration containing the access_definition, objects of these named subtypes do not require any run-time accessibility checking. We have allowed anonymous access types to be used in derived type declarations and generic instantiations, but they effectively lose their implicit convertibility at that point. We considered disallowing them, but could find no compelling reason to do so, and the usual generic contract model problems associated with going down that slippery slope. Similarly, we considered disallowing allocators for anonymous access types, but since they are already allowed for access parameters and access discriminants, there seemed no good reason to disallow them for these new contexts. Allowing constant declarations and function return types to use access_definitions is not critical to this proposal, and could be dropped. Constant declarations with access_definitions are no harder to support than access parameters (ditto goes for formal IN objects, I suppose). Function returns is harder to support, but also opens up new possibilities for creating functions which can return references to aliased components of objects that are themselves passed in using an access parameter. This would effectively allow functions that act as "selectors" that can be used on the left hand side of an assignment when followed by ".all". E.g: X : aliased Rec_With_Aliased_Component; begin Selected_Component(X'Access).all := Y; where Selected_Component is declared: function Selected_Component(RP : access Rec_With_Aliased_Component) return access Component_Type is begin return RP.Component'Access; end Selected_Component And if we approve the "object.operation" syntax: X.Selected_Component.all := Y; presuming Selected_Component is declared in the same package as Rec_With_Aliased_Component. There are some implementation issues associated with supporting function returns. Basically it means that such a function has to use run-time accessibility levels rather than static accessibility levels internally. Or more precisely, it needs to use accessibility levels that are comparable with those used by the caller. This need not be a huge burden. Probably the simplest is to have the caller pass in a "caller" accessibility level to the function, which the function then adds one to to use as its own accessibility level. [Some optimizations are possible: If there is only one access parameter, it could use the accessibility level associated with that parameter as the "caller" level (think about it ;-). If there are two or more access parameters, it could use the max of them. At that point, it would be more efficient to have the caller just pass in an extra parameter which is the "true" caller accessibility level. If it is nested in a function that also has access parameters, it is possible that it might have no access parameters, in which case it would probably need a "caller" accessibility level passed in as an additional parameter, though it could probably calculate it from the accessibility level of the access parameter passed into the enclosing function. Etc...] !appendix Randy Brukardt 00-04-13 This proposal was split out of the "with type" proposal (AI-00217) in April 2000. Some early conversation on this feature can be found in that AI's appendix. ************************************************************* From: Tucker Taft Sent: Monday, April 03, 2000 5:29 PM How about if we get an e-mail discussion going, then? The major new idea in my revision of AI-230 is the attribute on tagged types "'Class_Access". T'Class_Access is a type that may be used as the type of a stand-alone object, record or array component, parameter, etc. It is "universal" in the sense that when the expected type is T'Class_Access, any access type whose designated type is covered by T'Class may be used. There would need to be an accessibility check that the source type has the same accessibility level as type T. It would have "=" and "/=" operators, and the "null" literal. Allocators would raise Storage_Error, because the Storage_Size for T'Class_Access is defined to be 0. Such an access type would very closely match the reference-type implicit conversion semantics of Java and C++, providing "substitutability" for access-to-tagged types in much the way that T'Class supports substitutability for tagged types. T'Class_Access would be permitted on incomplete tagged types (a new category of incomplete types). I suppose we would also allow T'Class_Access on plain old incomplete types, with the same provisos as on T'Class (e.g. only in the same library unit and the full type must be tagged). T'Class_Access avoids some of the difficulties associated with the more general T'Access proposal, since it doesn't need to worry, e.g., about thin versus fat pointers, and loosens conversion rules only in the place where they seem most critical, namely dealing with conversions to access-to-'class types. The hope is that when combined with "with type T is tagged;", T'Class_Access will make bindings to Java-like languages much more straightforward both to create and to use. ************************************************************* From: Robert A Duff Sent: Tuesday, April 04, 2000 10:46 AM > How about if we get an e-mail discussion going, then? I like the T'Class_Access idea. But why not call it T'Access? But keep the rule that it's only for tagged, and the designated type is T'Class. That is, I'm just suggesting a name change. I don't see any benefit in the extra verbiage "Class_". Ada is already verbose enough, compared to Pascal's perfectly readable "^T" and C's somewhat ugly "T*". I'm not against verbosity when it imparts useful information, so let's not have a discussion of verbodity in general! >...Allocators would raise Storage_Error, because > the Storage_Size for T'Class_Access is defined to be 0. Does this mean I can use T'Class_Access in a pragma-Pure package? ************************************************************* From: Tucker Taft Sent: Tuesday, April 04, 2000 11:44 AM Robert A Duff wrote: > But why not call it T'Access? But keep the rule that it's only for > tagged, and the designated type is T'Class. That is, I'm just > suggesting a name change. I don't see any benefit in the extra verbiage > "Class_". I think there is an important benefit. At least *I* would presume that T'Access would be an access-to-T type rather than an access-to-T'Class type. Also, T'Class_Access is clearly only appropriate for tagged types, whereas T'Access seems like a perfectly reasonable thing to allow for any kind of type. > >...Allocators would raise Storage_Error, because > > the Storage_Size for T'Class_Access is defined to be 0. > > Does this mean I can use T'Class_Access in a pragma-Pure package? That was a possibility. If we allow access types in pure packages, we need certain restrictions. At a minimum, access types declared in pure packages should have Storage_Size 0. Since access parameters and discriminants are already allowed in pure packages, it seems unnecessary to go any further. However, we would have to amend the rules on shared passive packages to disallow not only the declaration of access-to-classwide types, but also the declaration of library-level objects of a type, or access types designating a type, with any part being of an access-to-classwide type. Alternatively, it might be easier to disallow T'Class_Access inside a pure library unit, if T is library-level (or a formal type), even though you could use T'Class_Access outside a pure library unit, despite the fact that T was declared inside a pure library unit. That seems more prudent for now. If we decide to allow storage-size-zero access types in pure packages in general, then we could examine allowing T'Class_Access there as well. Conceptually, we could think of Pure_Pkg.T'Class_Access being implicitly declared in a (virtual) impure child of Pure_Pkg, which is only visible to impure packages that "with" Pure_Pkg. ************************************************************* From: Robert A Duff Sent: Tuesday, April 04, 2000 12:02 PM > I think there is an important benefit. At least *I* would presume > that T'Access would be an access-to-T type rather than an access-to-T'Class > type. Also, T'Class_Access is clearly only appropriate for tagged > types, whereas T'Access seems like a perfectly reasonable thing to > allow for any kind of type. But none of that is likely to cause bugs. Another idea would be to call it T'Class'Access, presumably allowing: type T is tagged...; subtype S is T'Class; ... S'Access ... I'm not particularly advocating that. > That was a possibility. If we allow access types > in pure packages, we need certain restrictions. > At a minimum, access types declared in pure packages should > have Storage_Size 0. Since access parameters and discriminants > are already allowed in pure packages, it seems unnecessary > to go any further. However, we would have to amend the > rules on shared passive packages to disallow not only the declaration > of access-to-classwide types, but also the declaration of library-level > objects of a type, or access types designating a type, with any > part being of an access-to-classwide type. You realize this is a dangerous discussion. It's a side issue, but discussing it makes the original proposal look more complicated. ;-) > Alternatively, it might be easier to disallow T'Class_Access inside > a pure library unit, if T is library-level (or a formal type), > even though you could use T'Class_Access outside a pure library > unit, despite the fact that T was declared inside a pure library unit. I don't see the point of that. I want to declare self-referential data structures in pure packages. Of course, the creation routines have to be elsewhere (eg in an impure child). > That seems more prudent for now. If we decide to allow > storage-size-zero access types in pure packages in general, > then we could examine allowing T'Class_Access there as well. > > Conceptually, we could think of Pure_Pkg.T'Class_Access being implicitly > declared in a (virtual) impure child of Pure_Pkg, which is only visible > to impure packages that "with" Pure_Pkg. Sounds ugly to me. I don't like inventing all kinds of implicit junk all over. I advocate allowing it in the pure package, unless we actually have semantic problems with that. We already agreed that you can't do alligators. ************************************************************* From: Tucker Taft Sent: Tuesday, April 04, 2000 1:16 PM Robert A Duff wrote: > > > I think there is an important benefit. At least *I* would presume > > that T'Access would be an access-to-T type rather than an access-to-T'Class > > type. Also, T'Class_Access is clearly only appropriate for tagged > > types, whereas T'Access seems like a perfectly reasonable thing to > > allow for any kind of type. > > But none of that is likely to cause bugs. It is bound to cause confusion, in my view. Also, we might eventually want to allow T'Access as a generall anonymous access-to-T. If we used T'Access to mean access-to-T'Class, we would have eliminated that possibility. > Another idea would be to call it T'Class'Access, presumably allowing: > > type T is tagged...; > subtype S is T'Class; > ... S'Access ... > > I'm not particularly advocating that. That is where I started, but I rejected that because again it implied more generality than was provided. Note that T'Class'Access is the same number of characters as T'Class_Access ;-) > ... I advocate allowing it in the pure package, unless we > actually have semantic problems with that. We already agreed that you > can't do alligators. The semantic problems have to do with shared passive partitions, which are allowed to depend on pure packages, but which are not allowed to have access-to-class-wide objects, since they implicitly involve pointers to code that is potentially not as long-lived as the shared passive partition. I agree it is a side issue, but it is a thorny one. Perhaps the right answer is to presume that shared passive partitions need their own rules to prevent dangling references, and not to try too hard to make the rules of pure library units worry about them. On the other hand, we do need some well defined criteria for deciding what can go in a pure package. One goal is side-effect-freeness, but with access parameters and access discriminants, that is pretty much out the window. The other goal is ability to replicate freely among different partitions, since it has no "state" of its own. Perhaps the side-effect-freeness can be resurrected if we limit ourselves to cases where the parameters have no access-type parts. I suppose another way to say it is that the only side-effects are through parameters and data accessible via access-type parts of parameters. There is no variable "state" visible via up-level references that could be altered. We should probably also disallow the declaration of constants with any aliased parts, so the pure package remains position independent, and hence freely replicable. So I guess I am convinced -- force them to have storage size 0, and allow them in pure packages. Similarly, we should allow normal access-type declarations in pure packages, but with the storage size implicitly zero, while disallowing constants with aliased parts. Shared passive packages will need some amended rules to deal with the allowance of access types in pure packages. ************************************************************* From: Gary Dismukes Sent: Tuesday, April 04, 2000 2:11 PM > It is bound to cause confusion, in my view. Also, we might > eventually want to allow T'Access as a generall anonymous access-to-T. > If we used T'Access to mean access-to-T'Class, we would have eliminated > that possibility. Tuck, can you comment on the reason for not generalizing the implicit conversion capability to arbitrary designated types? At the September meeting we were talking in terms of an attribute T'univ_access which would allow implicit conversions to any access-to-D where D covers T and from any access-to-D where T covers D, but not restricted to tagged types. It probably makes sense to restrict the conversions so that it only goes towards one of these special types, but what's the reason for limiting it to class-wide types? Is it just because the main benefit and anticipated use is for those, or is there some fundamental difficulty with the generalization to other types? Or are you just being conservative in your old age? ;-) ************************************************************* From: Tucker Taft Sent: Tuesday, April 04, 2000 2:59 PM > Tuck, can you comment on the reason for not generalizing > the implicit conversion capability to arbitrary designated > types? There were some concerns about access-to-unconstrained-array, and whether it is thin or fat. I suppose there would also be a lot of anonymous access types popping up all over, with the associated "=" and "/=", if 'univ_access applied to all types. The minutes indicate there were some concerns about representation, but I don't remember the details. > ... Is it just because the main benefit > and anticipated use is for those, or is there some fundamental > difficulty with the generalization to other types? Or are > you just being conservative in your old age? ;-) These are all good reasons ;-) Since this is really trying to help with Java interfacing and "with type," the 'Class_Access seemed a smaller, more manageable change. I also think the proposed potentially-null anonymous access parameter "access all T"/"access constant T" solves the interfacing-to-C-pointer-parameter problems in a better way than would a more general T'Univ_Access. ************************************************************* From: Robert A Duff Sent: Tuesday, April 04, 2000 5:15 PM > The semantic problems have to do with shared passive partitions, which > are allowed to depend on pure packages, but which are not allowed to > have access-to-class-wide objects, since they implicitly involve > pointers to code that is potentially not as long-lived as the > shared passive partition. I agree it is a side issue, but it is > a thorny one. Perhaps the right answer is to presume that shared > passive partitions need their own rules to prevent dangling references, > and not to try too hard to make the rules of pure library units > worry about them. Yes. They can have some extra rules. > On the other hand, we do need some well defined criteria for deciding > what can go in a pure package. One goal is side-effect-freeness, but > with access parameters and access discriminants, that is pretty > much out the window. I thought the goal was to prevent silent side effects -- ie side effects on globals, whereas side effects on parameters (or what they point to) are OK. >... The other goal is ability to replicate freely > among different partitions, since it has no "state" of its own. > Perhaps the side-effect-freeness can be resurrected if we limit > ourselves to cases where the parameters have no access-type parts. > I suppose another way to say it is that the only side-effects are > through parameters and data accessible via access-type parts of > parameters. There is no variable "state" visible via up-level > references that could be altered. We should probably also disallow > the declaration of constants with any aliased parts, so the pure > package remains position independent, and hence freely replicable. I'm not sure I understand that. Could you give an example? > So I guess I am convinced ... Cool. It's not easy to convince Tucker of something. Not because he's stubborn, but because he's usually right. ;-) >... -- force them to have storage size 0, > and allow them in pure packages. Similarly, we should allow > normal access-type declarations in pure packages, but with > the storage size implicitly zero, while disallowing constants > with aliased parts. Shared passive packages will > need some amended rules to deal with the allowance of > access types in pure packages. Sounds good to me. ************************************************************* From: Robert A Duff Sent: Tuesday, April 04, 2000 5:24 PM > There were some concerns about access-to-unconstrained-array, and > whether it is thin or fat. I think Pascal raised a concern about a 64-bit machine, where it might make sense to have both 32-bit and 64-bit access types, where the user chooses by writing a rep clause. Pascal? > Since this is really trying to help with Java interfacing > and "with type," the 'Class_Access seemed a smaller, more > manageable change. I see it as a general feature. I think it's a serious flaw in Ada 95 that you have to write all kinds of type conversions that are perfectly safe. A type conversion ought to be a red flag, saying "I'm deliberately violating the type rules", but that doesn't work if you have to constantly "cry wolf". You can convert implicitly from T2 to T1'Class (where T2 is new T1) and you ought to be able to do the analogous thing for pointer-to-T2 and pointer-to-T1'Class. The 'Class_Access idea solves that. > I also think the proposed potentially-null anonymous access > parameter "access all T"/"access constant T" solves the > interfacing-to-C-pointer-parameter problems in a better way than > would a more general T'Univ_Access. Agreed. ************************************************************* From: Robert Dewar Sent: Wednesday, April 05, 2000 1:09 PM <> VMS being an obvious example, just so that this does not seem to be only a theoretical concern. ************************************************************* From: Pascal Leroy Sent: Thursday, April 06, 2000 4:22 AM Yes, any proposal which assumes that "all accesses look the same" is flawed. The 32-vs.-64-bit access types is not a theoretical issue, we do just that on Alpha because people don't want to pay for 64-bit pointers when their data structures are much smaller than 2Gb. ************************************************************* From: Christoph Grein Sent: Monday, May 08, 2000 11:45 PM Subject: [Ada-Comment] Predefined Access Types !topic Predefined Access Types !reference RM95-A.4.5(7,8), RM95-3.6.3, RM95-3.10 !from Christoph Grein 2000-05-09 !keywords access types, String_Access !discussion The type String_Access and corresponding function Free in A.4.5(7,8) seem misplaced in this package. They are not used there at all. In the light of the fact that when strings are handled, very often (I would even say, virtually always) an access type is also needed even if package Ada.Strings.Unbounded is not used, I would propose to shift these declarations to the place where type String is defined, 3.6.3. [And correspondingly for wide strings A.4.7.] This removes programmers' need to declare their own access types to strings all over the place. In a step further, I would propose a new 'Access attribute for types: Given any type T, T'Access would denote the following predefined general access type type T'Access is access all T; This would be implicitly defined where T is defined. Correspondingly also the type T'Class'Access would be predefined where 'Class is defined. [There would have to be rule to prevent recursion: Since T'Access is also a type, T'Access'Access and so on should be ruled out as being predefined.] If this is accepted, the type String_Access can be defined as subtype String_Access is String'Access; ************************************************************* From: Randy Brukardt Sent: Tuesday, May 09, 2000 6:31 PM To: 'Ada-Comment List' > In the light of the fact that when strings are handled, very often (I would > even say, virtually always) an access type is also needed even if package > Ada.Strings.Unbounded is not used, I would propose to shift these declarations > to the place where type String is defined, 3.6.3. [And correspondingly for > wide strings A.4.7.] This would be a very bad idea. Introducing names in Standard is *very* incompatible with existing code, as the names in Standard cannot be hidden, and would override any names currently accessible by a use clause. For instance, if a program contained: package P is type String_Access is access all My_String; end P; procedure M is use P; V : String_Access; ... Your proposal would change V's type (silently!) from P.String_Access to Standard.String_Access. One place that would happen is for the declarations in Ada.Strings.Unbounded that started the discussion! Besides, your second proposal is a better way to accomplish the same thing without polluting Standard. > In a step further, I would propose a new 'Access attribute for types: > Given any type T, T'Access would denote the following > predefined general access type > > type T'Access is access all T; This proposal looks rather attractive, but would be quite expensive on compilers hosted on memory-limited hosts. (Perhaps that doesn't matter anymore??) In any case, this exact proposal was made by Bob Duff in response to another proposal. I will attach your comment to that AI (AI-00230), because I don't want to spend anyone's time on the first proposal. ************************************************************* From: Robert A Duff Sent: Wednesday, May 10, 2000 10:14 AM > > type T'Access is access all T; > This proposal looks rather attractive, but would be quite expensive on > compilers hosted on memory-limited hosts. (Perhaps that doesn't matter > anymore??) I'm not sure why it is expensive. But I do think nobody should be running compilers on anything less than a 32-bit address space. (Target machines are often smaller, though.) > In any case, this exact proposal was made by Bob Duff in response to another > proposal. Actually, I think it was Robert Dewar's idea; I supported it. ************************************************************* From: Robert Dewar Sent: Tuesday, May 09, 2000 7:46 PM I strongly agree that introducing names into standard is a bad idea. As for type'Access, let's give credit where credit is due, I pushed this idea strongly during the design process, but it was rejected. note that the proposal in its current form is in any case incompatible with the current language design, which ascribes a quite different meaning top to type'Access in certain contexts. The objection to my proposal at the time was strong and clearly the majority viewpoint. The basis of this objection was that providing this distinguished anonymous type would tend to decrease type safety by encouraging the use of this type instead of properly typed access types. I see nothing that would change people's minds, and I think there is considerable merit in the majority viewpoint, so I see no argument for reopening this issue. By the way, the idea of putting this unreferenced type where it is was precisely to provide a standard string access type, does anyone use it this way? ************************************************************* From: Randy Brukardt Sent: Wednesday, May 10, 2000 11:44 AM > By the way, the idea of putting this unreferenced type where it is was > precisely to provide a standard string access type, does anyone use it > this way? I didn't even realize this type was in Ada.Strings.Unbounded until this comment, so for me at least, the answer is no. ************************************************************* From: Robert A Duff Sent: Wednesday, May 10, 2000 3:26 PM > I strongly agree that introducing names into standard is a bad idea. As Tuck is fond of pointing out, it's almost the same thing as adding a new reserved word to the language. > As for type'Access, let's give credit where credit is due, I pushed this > idea strongly during the design process, but it was rejected. Right. >... note that > the proposal in its current form is in any case incompatible with the > current language design, which ascribes a quite different meaning top > to type'Access in certain contexts. Heh? What's type'Access? > The objection to my proposal at the time was strong and clearly the majority > viewpoint. The basis of this objection was that providing this distinguished > anonymous type would tend to decrease type safety by encouraging the use of > this type instead of properly typed access types. I see nothing that would > change people's minds, and I think there is considerable merit in the majority > viewpoint, so I see no argument for reopening this issue. I see no merit whatsoever in the majority viewpoint. Most programs I've seen (or written) declare exactly one access type per designated type, right after the designated type is declared. So in practise, people are *not* taking advantage of strongly typed access types. Contrast this with (for example) integer types, where most programmers define a new integer type for each distinct purpose in the program. I think there *is* new information on the subject: people have realized from experience with Ada 95 that it's a big pain to have type conversions all over the place for perfectly safe cases (eg, access-to-T2'Class converted to access-to-T1'Class, where T2 is derived from T1, so conversions from T2'Class to T1'Class are of course implicit). These bogus type conversions damage readability. And part of the solution that has been discussed involves the T'Access idea. > By the way, the idea of putting this unreferenced type where it is was > precisely to provide a standard string access type, does anyone use it > this way? I doubt it. Lots of programs don't use unbounded strings, so it wouldn't occur to the programmer to use this type. But it's harmless, so no change is needed. We're certainly not going to delete the type, and we're certainly not going to add a new type to package Standard. ************************************************************* From: Gary Dismukes [dismukes@gnat.com] Sent: Wednesday, May 10, 2000 5:08 PM > >... note that > > the proposal in its current form is in any case incompatible with the > > current language design, which ascribes a quite different meaning top > > to type'Access in certain contexts. > > Heh? What's type'Access? I'm guessing that Robert's referring to the case where the prefix is a current instance name (looks like a type name, though technically it's the name of an object of course). ************************************************************* From: Robert Dewar Sent: Wednesday, May 10, 2000 7:48 PM Yup! That's what I was referring to, that is indeed the only context in which type'access can appear in the current language. ************************************************************* From: Robert A Duff Sent: Thursday, May 11, 2000 9:46 AM > > Heh? What's type'Access? > > I'm guessing that Robert's referring to the case where the prefix > is a current instance name (looks like a type name, though technically > it's the name of an object of course). Isn't it *always* the name of the instance? I mean, even if we chose to call it T'Pointer, we would have a problem, because the attribute would be unusable inside the type. Not a big problem, but it would be annoying, because access types are quite often used to make self-referential record types. ************************************************************* From: Robert Dewar [dewar@gnat.com] Sent: Thursday, May 11, 2000 3:47 AM To: ada-comment@ada-auth.org Subject: Re: [Ada-Comment] Predefined Access Types <> Much more significantly, within tasks and protected objects to denote the current concurrent object. ************************************************************* From: Gary Dismukes Sent: Thursday, May 11, 2000 1:34 PM > Isn't it *always* the name of the instance? I mean, even if we chose to > call it T'Pointer, we would have a problem, because the attribute would > be unusable inside the type. Not a big problem, but it would be > annoying, because access types are quite often used to make > self-referential record types. Yes, that's right, it will always denote the instance within the type, though I suppose that if a new attribute such as 'Pointer or whatever were used it could be defined to apply to the type of the object in the case of an object prefix, hmm. Anywya, as you say, the restriction within a type is annoying but doesn't seem like a major problem. You could still use a workaround such as applying 'Access to a subtype name. ************************************************************* From: Robert Dewar Sent: Wednesday, May 10, 2000 7:52 PM <> Ah Bob, if you supported it, then you can't move for a reconsideration. To convince ourselves it is worth refighting this, we have to have at least one person change their minds :-) ************************************************************* From: Christoph Grein Sent: Thursday, May 11, 2000 12:00 AM > I strongly agree that introducing names into standard is a bad idea. OK, I see the point. > .... note that > the proposal in its current form is in any case incompatible with the > current language design, which ascribes a quite different meaning top > to type'Access in certain contexts. RM K(2): P'Access where P denotes a subprogram RM K(4): X'Access where X denotes an object Where is T'Access defined? Oh - within record type definitions where it stands for the current instance of the type. > By the way, the idea of putting this unreferenced type where it is was > precisely to provide a standard string access type, does anyone use it > this way? > No, I dislike the idea of withing Strings.Unbounded just for this type when I do not use any other operations of the package. So the type is really misplaced. The proper place in light of all the arguments presented seems to be package Strings (RM A.4.1). ************************************************************* From: Robert A Duff Sent: Thursday, May 11, 2000 7:28 AM > The proper place in light of all the arguments presented seems to be > package Strings (RM A.4.1). Package Strings has pragma Pure, which disallows access types. Come to think of it, Standard has pragma Pure, too, which is *another* reason we can't put type String_Access in Standard. By the way, I wish there were a way to declare access types without allocators; then we could allow *those* kinds of access types in pragma-pure packages. I agree with you that String_Access is in a weird place. But it's harmless. If you don't want to use it, you can easily declare your own. Not ideal, but it works. ************************************************************* From: Michael Yoder Sent: Thursday, May 11, 2000 10:11 AM Christopher Grein wrote: > >The proper place in light of all the arguments presented seems to be >package Strings (RM A.4.1). > Doing this would require (under current rules) changing package Strings from pure to preelaborated. This potentially breaks existing code; it seems unlikely that a user would write an existing pure package that depends on Strings, but it's certainly imaginable (e.g., by renaming the exceptions). Earlier someone asked if anyone ever used the access type in Strings.Unbounded. I have, two or three times. In each case, I knew other parts of the program were using unbounded strings, so there was no cost to doing so. I believe however that I would do it in any case, since IMO most large programs use unbounded strings at least once, and a small program won't be made a large one just by including one extra package. Even so, I agree the type doesn't belong where it's put, and I have encountered at least one space-constrained program for which this consideration mattered. Perhaps a least bad solution would be to put the type in its own small child of Strings, and make the type in Strings.Unbounded be a "renaming as subtype" of that type. This would (I think) be entirely compatible with the existing state of affairs. ************************************************************* From: Christoph Grein Sent: Friday, May 12, 2000 12:01 AM > Doing this would require (under current rules) changing package Strings > from pure to preelaborated. ... OK, I again see the point. > Perhaps a least bad solution would be to put the type in its own small > child of Strings, and make the type in Strings.Unbounded be a "renaming as > subtype" of that type. This would (I think) be entirely compatible with > the existing state of affairs. Hey, I think that's a brilliant idea. An access to String is so often needed that it should be predefined in the language, and Michael's proposal just does this in an innocuous way. package Ada.Strings.Yoder is pragma Preelaborate(Yoder); type String_Access is access all String; procedure Free (X : in out String_Access); end Ada.Strings.Yoder; ************************************************************* From: Robert Dewar Sent: Friday, May 12, 2000 12:59 AM You can even imagine a special implementation of Ada.Strings;Yoder that would use some special storage pool to handle string accesses especially efficiently??? ************************************************************* From: Michael Yoder Sent: Friday, May 12, 2000 2:30 PM This is a good idea in any case (that is, it can be done for the type in Strings.Unbounded even if Strings.Yoder never becomes part of Ada0X :-). ************************************************************* From: Robert A Duff Sent: Thursday, May 11, 2000 8:21 PM > Bob, were you for or against type'Access the first time around? > I can't remember :-) Sometimes I can't remember what I was for or against in the past ;-), but in this case I've been for it, or something like it, all along. ... > Ah Bob, if you supported it, then you can't move for a reconsideration. > To convince ourselves it is worth refighting this, we have to have at > least one person change their minds :-) OK. But it *was* brought up again, independently, as part of the solution to some other AI. I can't remember which. (*Editor's note: This one!*) ************************************************************* From: Robert Dewar Sent: Friday, May 12, 2000 12:57 AM Well I sure would like to see something like typ'Access come back if it can be figured out how to do it cleanly. ************************************************************* From: Christoph Grein Sent: Friday, May 12, 2000 12:14 AM > < stands for the current instance of the type. > >> > > Much more significantly, within tasks and protected objects to denote > the current concurrent object. > Thank you, Robert, for the details. Wouldn't it be a good idea to include T'Access with such a hint in Annex K? This annex is "informative", so IMO a good place for a statement like this. ************************************************************* From: Robert Dewar Sent: Friday, May 12, 2000 1:05 AM <> Well this already is in Annex K: 4 X'Access For a prefix X that denotes an aliased view of an object: THe case of subtype_name'Access is just a special case where subtype_name is defined to denote a specific aliased view, namely the current instance. It would be confusing to have an entry saying T'Access For a prefix that denotes a subtype T, ... since in this case T does not denote a subtype. I suppose one could argue for a note, but my feeling is that notes belong in text books, not in the RM. Also notes in informative annexes are a bit odd I would think. Although this is a summary and is informative, it is definitely written in the style of normative text, so a note still needs to be labeled a note I would think. ************************************************************* From: Robert A Duff Sent: Friday, May 12, 2000 1:14 PM > I suppose one could argue for a note, but my feeling is that notes belong > in text books, not in the RM. Also notes in informative annexes are a bit > odd I would think. I guess they would be doubly informative. ;-) > Although this is a summary and is informative, it is definitely written > in the style of normative text, ... In fact, this text is identical to the normative text in the body of the RM that describes these attributes. So it's not surprising that it's in the same style. ;-) In the source code for the RM (in Scribe), the attributes are written as macro calls, which generate the inline text, and also send the same text to a separate file, which gets sorted by attribute name, and then re-included back into Annex K. The pragmas have a similar mechanism. I think to build the Postscript version of the RM, you had to run Scribe three times in a row, because the output of one run would get sucked up into the next run as input, and it had to "settle down". Sort of like bootstrapping a compiler. Randy is in the process of modernizing this software. ;-) >... so a note still needs to be labeled a > note I would think. I tend to think it's not the job of ARG to teach people Ada. As Robert says, there are textbooks. ************************************************************* From: Robert A Duff Sent: Friday, May 12, 2000 4:04 PM Mike and Robert, > Robert Dewar wrote: > >You can even imagine a special implementation of Ada.Strings;Yoder that > >would use some special storage pool to handle string accesses > >especially efficiently??? > > This is a good idea in any case (that is, it can be done for the type in > Strings.Unbounded even if Strings.Yoder never becomes part of Ada0X :-). I guess you're going to be famous, Mike. Nobody else has a predefined Ada package named after them. Hey, maybe the ARG could make money by letting large corporations put their names on things. Package Calendar could be renamed package FleetBank, and so on. Anyway, I'm not sure what you guys are getting at with efficient storage pools. What's special about String_Access? The fact that the designated type is an unconstrained array? Surely not the fact that it's predefined. What sort of special pool are you talking about, and whatever it is, why wouldn't it be a good idea for *any* "type Mumble is access all Unconstrained_Array;" that appears anywhere in any program? ************************************************************* From: Robert A Duff Sent: Friday, May 12, 2000 4:38 PM I wrote: > I guess you're going to be famous, Mike. Nobody else has a predefined > Ada package named after them. Except for Ada herself, of course! ************************************************************* From: Michael Yoder Sent: Monday, May 15, 2000 9:25 AM Bob Duff wrote: >Anyway, I'm not sure what you guys are getting at with efficient storage >pools. What's special about String_Access? The fact that the >designated type is an unconstrained array? Surely not the fact that >it's predefined. What sort of special pool are you talking about, and >whatever it is, why wouldn't it be a good idea for *any* "type Mumble is >access all Unconstrained_Array;" that appears anywhere in any program? String_Access is special because you can probably improve performance by making assumptions about the frequency of allocation of various lengths. A simpler possibility is to choose the algorithm so as to specifically support Strings.Unbounded : this can be done by usiing a binary-buddy allocator when the length is a power of 2, for example. (I haven't actually tried any such scheme, so I suppose I should qualify my enthusiasm by saying that the idea is potentially good rather than good. But the idea of exploring such schemes is good. :-) If Ada had a predefined generic for vectors of variable length, it could probably use the same allocator as that for Strings.Unbounded. If the above is still overly concise, I'm willing to elaborate further. ************************************************************* From: Michael Yoder Sent: Monday, May 15, 2000 11:36 AM Robert Duff wrote: >I guess you're going to be famous, Mike. Nobody else has a predefined >Ada package named after them. Hey, maybe the ARG could make money by >letting large corporations put their names on things. Package Calendar >could be renamed package FleetBank, and so on. I would hate to have to buy dark glasses in order to travel incognito. :-) So, let me propose Ada.Strings.Accesses as a name for this supposed package. >Anyway, I'm not sure what you guys are getting at with efficient storage >pools. I should perhaps state that my experience makes me at least as inclined to worry about fragmentation behavior as efficiency. In either case, there is potential benefit in treating strings specially. ************************************************************* From: Robert Dewar Sent: Monday, October 1, 2001 5:57 AM I think that all AI's that propose new features should have a section discussing the need for any work in the area. I am afraid we are going into the mode of language experts writing up things that would be nice to have, if we are not careful. ************************************************************* From: Tucker Taft Sent: Monday, October 1, 2001 10:44 AM I believe that is at least part of the intent of the "!problem" section. Apparently the "problem" section of this AI was inadequate. Also, in this case, we discussed the need quite a bit at the last ARG meeting, so I was more focused on writing up the technical aspects of the proposal, than justifying its need. I do agree with the important of having a good justification. ************************************************************* From: Robert Dewar Sent: Monday, October 1, 2001 11:00 AM The important thing here is that the justification include some evidence that this is a real world issue, i.e. a purely technical nice-to-have justification is dubious. We need some real world examples or input. ************************************************************* From: Randy Brukardt Sent: Monday, October 1, 2001 8:05 PM Robert said: > I think that all AI's that propose new features should have a section > discussing the need for any work in the area. I am afraid we are going > into the mode of language experts writing up things that would be nice > to have, if we are not careful. As Tucker responded, this is the propose of the !problem section. If the !problem of an AI isn't convincing, then the AI has a (ahem) problem, no matter what the merits of the proposal. > The important thing here is that the justification include some evidence > that this is a real world issue, i.e. a purely technical nice-to-have > justification is dubious. We need some real world examples or input. My own guess is that is going to be hard to come by on this one. This proposal grew out an attempt to save "with type"; now that that has been scuttled, the need for this one is much less compelling. At least, this proposal gets rid of the run-time accessibility for every object that we had discussed at the last meeting. But I'm still concerned that static accessibility might not be enough to implement this (especially in shared generics, where the static level /= instantiation level). If I ever get some spare time, I'll have to think about this one some more. ************************************************************* From: Robert Dewar Sent: Monday, October 1, 2001 8:27 PM <> The important thing to realize about proposals for additions is that the dynamics have in my view shifted completely. In the old days, the ARG could via WG9 and ACATS essentially command all implementors to implement feature X and they had to jump. Now, at least speaking for ACT, but I suspect for other vendors too, the issue of whether new features get implemented is far more dependent on what real customers want. If a new feature is approved, or even "mandated" it will not get implemented unless customers need/want it implemented and resources are consequently available. That's why it is so important to make sure that real demand exists before we sit around designing neat features that would be nice to have. ************************************************************* From: Tucker Taft Sent: Monday, October 1, 2001 11:29 PM Randy Brukardt wrote: > ... > > The important thing here is that the justification include some evidence > > that this is a real world issue, i.e. a purely technical nice-to-have > > justification is dubious. We need some real world examples or input. > > My own guess is that is going to be hard to come by on this one. This > proposal grew out an attempt to save "with type"; now that that has been > scuttled, the need for this one is much less compelling. I don't see that as the primary justification. The major need relates to the large number of unnecessary explicit conversions when using Ada 95 for "normal" OO-style programming. The connection with "with type" was pretty remote, in my view. > > At least, this proposal gets rid of the run-time accessibility for every > object that we had discussed at the last meeting. But I'm still concerned > that static accessibility might not be enough to implement this (especially > in shared generics, where the static level /= instantiation level). > > If I ever get some spare time, I'll have to think about this one some more. In thinking about this more, I have concluded that we should allow access_definitions in component subtype indications, but with the same rules as for discriminants, namely that the accessibility level of the anon subtype is the same as the level of the enclosing composite object. This jibes with the fact that typically a set of objects that point at each other all have the same lifetime. I didn't adequately deal with allocators. I think if an allocator appears as the expression of a return statement, where the return type is specified using an access_definition, then the storage pool to use for the allocator is determined by the caller. This creates a very useful capability for a function to do an allocation in a storage pool determined by context. This is a fundamental requirement for region-based memory allocation, which is becoming recognized as the "thinking person's alternative" to full garbage collection. This argues for a uniform treatment of such functions, namely that they are implicitly passed both the "caller" accessibility level and the target storage pool for allocators. ************************************************************* From: Robert Dewar Sent: Tuesday, October 2, 2001 5:22 AM <> That's one level remote to me, I need a "major need" to be expressed in terms of actual people writing actual code with actual needs and examples. I am afraid that the ARG is trying to take on the job of requirements gathering for language enhancements without sufficient connection to the outside world. We haven't even asked *vendors* what they think is important, let alone asking actual Ada users. Language designers are not the right people to be deciding on what is really important to add. For example, if you were to ask ACT what the single most important feature needed was, I suspect it would be C++ interfacing features. I certainly can't remember any customer asking about "large number of unnecessary explicit conversions" :-) ************************************************************* From: Randy Brukardt Sent: Tuesday, October 2, 2001 1:18 PM > I am afraid that the ARG is trying to take on the job of requirements > gathering for language enhancements without sufficient connection to > the outside world. We haven't even asked *vendors* what they think is > important, let alone asking actual Ada users. Many vendors participate in this group, and have rarely been shy about expressing their views. Certainly, ACT has been happy to provide this at every opportunity. :-) But I would caution against using requests to vendors as the only criteria. The Ada community has a strong commitment to following standards, and thus I would not expect most customers to ask their vendor to "break" the standard. Therefore, I'd expect enhancement requests to vendors to involve areas outside of the standard (interfacing to other languages, additional provided packages, performance issues, etc.), and most of that isn't interesting to the ARG any. To take a specific example. When we were building Claw, we wasted a lot of time tracking down "bugs" caused by broken overridding (where we thought some routine was overridding, but wasn't due to a spelling error or missing parameter). We didn't run to a vendor (even though I probably could have convinced one to do something :-) to fix this: we just put it down to bad language design and lived with it. The only thing we did is mention it toward the end of our paper on Claw. Only when I wrote up an amendment AI on the topic (mainly to provide a fully fleshed out example AI to get comments on the format of an amendment) did I find out that many other people shared this frustration. I doubt anyone ran to ACT to ask for an enhancement here (although they might now that there is a fully defined solution). > Language designers are not the right people to be deciding on what is > really important to add. This is true, but I would argue that the majority of the ARG membership aren't "language designers" per se, but vendors and/or users of Ada. Of course, everyone is a "language designer" from time-to-time. > I need a "major need" to be expressed > in terms of actual people writing actual code with actual needs and > examples. For this particular AI, I certainly agree. So far as I remember, the problem was driven by complaints from Erhard's students. While these are "actual people", I have my doubts that they meet the "actual needs" qualification. Moreover, we built Claw (certainly a large O-O system) without running into this problem. I would much rather have "in out" parameters on functions (as that would fix a real problem that we have had with O-O programs) than this proposal [access parameters are not a real replacement for "in out" parameters, as the calls are much more complex]. ************************************************************* From: Robert Dewar Sent: Tuesday, October 2, 2001 1:44 PM <> There is a different between having some technical person participating in the ARG meetings, and getting formal input from vendors. <> The ARG should be more interested in such issues. yes, I know it is more fun for language designers to design neat new features -- and that's my point. Surely we should not use requests to vendors as the only criterion, but it's a better sole criterion than using the input from language designers as the only criterion. In fact we get a wide variety of requests from customers, after all, WITH TYPE is there because customers needed it, not because there was some AI suggesting it, as an example. <> Remember that in our environment, customers ask us if they have any questions or problems whatsoever in using Ada. All the time, they are asking us "how do we do this in Ada", or "can't we find a better way of doing things than this". So indeed we have lots of input of this kind, but I can't find many things that would be worth new language features. Right now, I think there is a real danger of designing language features that no one will implement, and thus making an updated standard irrelevant. <> The lack of in out parameters in functions, a restriction that as far as I can tell is, like the peculiar declaration ordering rules in 83, there only because someone thinks it is more consistent with some particular coding philosophy (*), is indeed a significant problem. Robert Dewar (*) I continue to find it odd that the design principle for functions in the Ada language is "functions can have arbitrary side effects, but no hint of this is allowed in the function specification. If you want to make a state change in a function, it cannot be done using IN OUT parameters in the spec, instead it must be done covertly using global variables" :-) ************************************************************* From: Dan Eilers Sent: Tuesday, October 2, 2001 2:13 PM Robert Dewar wrote: > (*) I continue to find it odd that the design principle for functions in > the Ada language is "functions can have arbitrary side effects, but no > hint of this is allowed in the function specification. If you want to > make a state change in a function, it cannot be done using IN OUT > parameters in the spec, instead it must be done covertly using global > variables" :-) Well, to some extent, declaring a global variable is an overt invitation for modification by any code within its scope. The covertness problem with IN OUT parameters on functions is that there is no indication at the point of the call that parameters might be modified, where such parameters are likely to be local variables with no signal to the reader that they are modified by the function call. I believe this problem was pointed out in C.A.R. Hoare's famous 1973 paper "Hints on Programming Language Design". ************************************************************* From: Randy Brukardt Sent: Tuesday, October 2, 2001 3:08 PM Which of course applies equally to procedure calls. And I have been occassionally surprised by procedures modifying parameters, and it would be nice if that was identified in the call. But it seems about 20 years too late to complain about that... ************************************************************* From: Robert Dewar Sent: Tuesday, October 2, 2001 10:39 PM Fine, people who have this point of view can restrict their use of the language. No one suggests removing USE clauses just because some people think they are a bad idea. ************************************************************* From: Dave Emery Sent: Tuesday, October 2, 2001 2:10 PM At 14:44 -0400 10/2/01, dewar@GNAT.COM wrote: >... >The lack of in out parameters in functions, a restriction that as far as >I can tell is, like the peculiar declaration ordering rules in 83, there >only because someone thinks it is more consistent with some particular >coding philosophy (*), is indeed a significant problem. Can I vote for reconsidering/removing this (stupid) restriction? If one argument in favor of keeping it is to allow the compiler or some third-party verification tool to assume or to check that the function has no side-effects, I'd rather do that check with a pragma, and allow/trust the user to do the right thing at the right time. Certainly this has been a very painful restriction for interfacing with other languages that do not accept this point of dogma :-) ************************************************************* From: Randy Brukardt Sent: Tuesday, October 2, 2001 3:03 PM > The ARG should be more interested in such issues. yes, I know it is more > fun for language designers to design neat new features -- and that's my > point. I understand, but in practice, there haven't been much in the way of expanding the language. When I proposed the Ada.Directories package, there was a lot of opposition of "not important enough" (and you originally led the charge on that). As far as C++ interfacing goes, we discussed this at the Westboro meeting (September 1999), but no one had any proposals on what to do. The existing work was all rather implementation-dependent. (Ed was at that meeting, and presented various GNAT features to the group, but I don't recall if he was there for this discussion.) And so far as I know, nothing has been proposed since. > Remember that in our environment, customers ask us if they have any > questions or problems whatsoever in using Ada. All the time, they > are asking us "how do we do this in Ada", or "can't we find a better > way of doing things than this". So indeed we have lots of input of > this kind, but I can't find many things that would be worth > new language features. I also get questions of the sort of "how do you do X?", but I'm never thinking about new language features when I answer them. "Wait until 2006" doesn't seem likely to satisfy many customers! > Right now, I think there is a real danger of designing language features > that no one will implement, and thus making an updated standard irrelevant. Understandable, and AI-230 is certainly a possible offender in this area. > The lack of in out parameters in functions, a restriction that as far as > I can tell is, like the peculiar declaration ordering rules in 83, there > only because someone thinks it is more consistent with some particular > coding philosophy (*), is indeed a significant problem. I've always figured that I should have the power to re-open this issue, as I was one of the people who fought tooth-and-nail to keep it in Ada 95. The main reason is that the Janus/Ada intermediate code does not allow copy-back for function calls -- and changing this would be a very large change to the optimizer and code generator. (Function calls always discard their parameters.) My mind was changed by our work on Claw. The first problem was a query function: function Is_Something (Window : in Root_Window_Type) return Boolean is begin -- Long calculation involving several system calls. return Answer; end Is_Something; Is_Something (I forget the exact function involved) was likely to be called frequently, so I wanted to save the result I calculated in the Window object. So I added a component to save the value and a component to say whether the first component was, and got a compile-time error trying to set them. Ugh. The problem has occurred repeatedly during the development of Claw. Some operations that we would have preferred to be functions ended up as procedures since we needed to modify the object. On a few occasions, we used the fact that Claw objects are assignable, and "clones" of each other to work around the problem: function Is_Something (Window : in Root_Window_Type) return Boolean is Writable_Copy : Root_Window_Type'Class := Window; begin -- Modify components of Writable_Copy, which modifies the original object. return Answer; end Is_Something; But that is horrible (and inefficient). I've tried to raise the "in out" issue at the ARG meetings without success. People are afraid that the same old bunch of opponents (minus at least one -- me!) would resurface. *************************************************************