CVS difference for ais/ai-00345.txt

Differences between 1.22 and version 1.23
Log of other versions for file ais/ai-00345.txt

--- ais/ai-00345.txt	2005/08/21 06:00:31	1.22
+++ ais/ai-00345.txt	2005/10/31 05:18:32	1.23
@@ -1,4 +1,4 @@
-!standard  3.09.01    (03)                             05-07-25  AI95-00345/10
+!standard  3.09.01    (03)                             05-09-20  AI95-00345/11
 !standard  2.09       (02)
 !standard  3.02       (12)
 !standard  3.02       (13)
@@ -21,9 +21,9 @@
 !standard  9.07.02    (04)
 !standard  9.07.04    (04)
 !standard  9.07.04    (06)
-!standard  9.08       (03)
-!standard  9.09       (01)
+!standard 10.02.01    (11)
 !standard 12.05.05    (01)
+!standard J.09        (03)
 !class amendment 03-08-07
 !status Amendment 200Y 04-07-02
 !status WG9 approved 04-11-18
@@ -289,19 +289,20 @@
              access-to-object
              access-to-subprogram
        composite
-          noninterface
+          untagged
              array
                 string
                 other array
              record
              task
              protected
-          interface
-             nonlimited interface
-             limited interface
-                synchronized interface
-                   task interface
-                   protected interface
+          tagged (including interfaces)
+             nonlimited tagged record
+             limited tagged
+                limited tagged record
+                synchronized tagged
+                   tagged task
+                   tagged protected
 
 
     There are other classes, such as "numeric" and "tagged", which
@@ -322,11 +323,11 @@
     may be defined. A]{a}s for any derived type, additional primitive
     subprograms may be defined, and inherited primitive subprograms may
     be overridden.] The derived type is called an extension of [the] {its}
-    ancestor type{(s)}, or simply a type extension.
+    ancestor type{s}, or simply a type extension.
 
     Every type extension is also a
     tagged type, and is either a record extension {of some other tagged
-    type,}[ or] a private extension{, or a task or protected type
+    type,}[ or] a private extension{, or a non-interface task or protected type
     derived from an interface type (a synchronized tagged type -- see 3.9.4)}
     [of some other tagged type]. A record extension is defined by a
     derived_type_definition with a record_extension_part{ (see 3.9.1),
@@ -402,26 +403,42 @@
      interface*, a *task interface*, a *protected interface*, or a
      *synchronized interface*. In addition, all task and protected interfaces
      are synchronized interfaces, and all synchronized interfaces are limited
-     interfaces. A view of an object that is of a task interface type (or of a
-     corresponding class-wide type) is a task object. Similarly, a view of an
-     object that is of a protected interface type (or of a corresponding
-     class-wide type) is a protected object.
+     interfaces.
 
      A task or protected type derived from an interface is a tagged type. Such
      a tagged type is called a *synchronized* tagged type, as are synchronized
      interfaces and private extensions derived from synchronized interfaces.
 
+     A task interface is a (tagged, abstract) task type.
+     A protected interface is a (tagged, abstract) protected type.
+
+
   Change 3.9.4(8) to:
+
+     A type derived from a nonlimited interface shall be nonlimited.
 
-     A descendant of a nonlimited interface shall be nonlimited. A descendant
-     of a task interface shall be a task type or a task interface. A descendant
-     of a protected interface shall be a protected type or a protected
-     interface. A descendant of a synchronized interface shall be a task type,
-     a protected type, or a synchronized interface.
+     An interface derived from a task interface shall include the reserved word
+     *task* in its definition; any other type derived from a task interface
+     shall be a private extension or a task type declared by a task declaration
+     (see 9.1).
+
+     An interface derived from a protected interface shall include the reserved
+     word *protected* in its definition; any other type derived from a
+     protected interface shall be a private extension or a protected type
+     declared by a protected declaration (see 9.4).
+
+     An interface derived from a synchronized interface shall include one of
+     the reserved words *task*, *protected*, or *synchronized* in its
+     definition; any other type derived from a synchronized interface shall be
+     a private extension, a task type declared by a task declaration, or a
+     protected type declared by a protected declaration.
 
+     No type shall be derived from both a task interface and a protected
+     interface.
+
    AARM Note:
 
-       We require that a descendant of a task, protected, or synchronized
+       We require that am interface descendant of a task, protected, or synchronized
        interface repeat the explicit kind of interface it will be, rather than
        simply inheriting it, so that a reader is always aware of whether the
        interface provides synchronization and whether it may be implemented
@@ -433,6 +450,12 @@
        Hence, we require the kind of the actual interface to match the kind of
        the formal interface (see 12.5.5).
 
+       The last rule prevents a single private extension from inheriting from
+       both a task and a protected interface. For a private type, there can be
+       no legal completion. For a generic formal type, there can be no possible
+       matching type (so no instantiation could be legal). The rule provides
+       early detection of the errors.
+
  [end of AI-251-relative modifications]
 
 Add after 6.3.1(24):
@@ -635,16 +658,16 @@
     not implemented by an entry, the call proceeds as described in 6.4,
     followed by the sequence_of_statements of the triggering_alternative;
     the abortable_part is never started.}
-
-Modify 9.8(3):
 
-    Each task_name is expected to be of any task type {or task interface type};
-    they need not all be of the same [task] type.
+Modify J.9(3):
+   Storage_Size may be specified for a task first subtype that is not
+   an interface via an attribute_definition_clause.
 
-Modify 9.9(1):
 
-    For a prefix T that is of a task type {or task interface type} (after any
-    implicit dereference), the following attributes are defined:
+In the wording of AI-161:
+  Add "interface types" to the list of types that have preelaborable
+  initialization. Limit Preelaborable_Initialization pragma to specific
+  non-interface protected types.
 
 In the wording of AI-251:
 
@@ -1076,19 +1099,20 @@
 @ @ @ @ @ @ access-to-object@hr
 @ @ @ @ @ @ access-to-subprogram@hr
 @ @ @ @ composite@hr
-@ @ @ @ @ @ noninterface@hr
+@ @ @ @ @ @ untagged@hr
 @ @ @ @ @ @ @ @ array@hr
 @ @ @ @ @ @ @ @ @ @ string@hr
 @ @ @ @ @ @ @ @ @ @ other array@hr
 @ @ @ @ @ @ @ @ record@hr
 @ @ @ @ @ @ @ @ task@hr
 @ @ @ @ @ @ @ @ protected@hr
-@ @ @ @ @ @ interface@hr
-@ @ @ @ @ @ @ @ nonlimited interface@hr
-@ @ @ @ @ @ @ @ limited interface@hr
-@ @ @ @ @ @ @ @ @ @ synchronized interface@hr
-@ @ @ @ @ @ @ @ @ @ @ @ task interface@hr
-@ @ @ @ @ @ @ @ @ @ @ @ protected interface>>
+@ @ @ @ @ @ tagged (including interfaces)@hr
+@ @ @ @ @ @ @ @ nonlimited tagged record@hr
+@ @ @ @ @ @ @ @ limited tagged@hr
+@ @ @ @ @ @ @ @ @ @ limited tagged record@hr
+@ @ @ @ @ @ @ @ @ @ synchronized tagged@hr
+@ @ @ @ @ @ @ @ @ @ @ @ tagged task@hr
+@ @ @ @ @ @ @ @ @ @ @ @ tagged protected>>
 
 !corrigendum 3.2(13)
 
@@ -1097,7 +1121,7 @@
 classification dimensions and do not fit into the above strictly hierarchical
 picture.>>
 @dby
-@xindent<@s9<There are other classes, such as "numeric" and "tagged", which
+@xindent<@s9<There are other classes, such as "numeric" and "discriminated", which
 represent other classification dimensions, but do not fit
 into the above strictly hierarchical picture.>>
 
@@ -1131,12 +1155,13 @@
 type is a tagged type (see 3.9.4). When deriving from a tagged
 type, as for any derived type, additional primitive subprograms may
 be defined, and inherited primitive subprograms may be overridden.
-The derived type is called an @i<extension> of its ancestor type(s), or
+The derived type is called an @i<extension> of its ancestor types, or
 simply a @i<type extension>.
 
 Every type extension is also a tagged type, and is either a @i<record
 extension> of some other tagged type, a @i<private extension>, or a
-task or protected type derived from an interface type (a synchronized tagged
+non-interface task or protected type derived from an interface type (a
+synchronized tagged
 type @emdash see 3.9.4). A record extension is defined by a
 @fa<derived_type_definition> with a @fa<record_extension_part> (see 3.9.1),
 which may include the definition of additional components. A private
@@ -1180,8 +1205,8 @@
 For the execution of a call on a dispatching operation, the action performed is
 determined by the properties of the corresponding dispatching operation of the
 specific type identified by the controlling tag value. If the corresponding
-operation is explicitly declared for this type, Redundant[even if the
-declaration occurs in a private part], then the action comprises an invocation
+operation is explicitly declared for this type, even if the
+declaration occurs in a private part, then the action comprises an invocation
 of the explicit body for the operation. If the corresponding operation is
 implicitly declared for this type:
 
@@ -1353,9 +1378,9 @@
    >@ft<@b<protected type>>@fa< defining_identifier [known_discriminant_part] [>@ft<@b<is>>@fa< protected_definition];>>
 @dby
 @xcode<@fa<protected_type_declaration ::=
-   >@ft<@b<protected type>>@fa< defining_identifier [known_discriminant_part] [>@ft<@b<is>>@fa<
+   >@ft<@b<protected type>>@fa< defining_identifier [known_discriminant_part] >@ft<@b<is>>@fa<
       [>@ft<@b<new>>@fa< interface_list >@ft<@b<with>>@fa<]
-      protected_definition];>>
+      protected_definition;>>
 
 !corrigendum 9.4(10)
 
@@ -1537,33 +1562,36 @@
 described in 6.4, followed by the @fa<sequence_of_statements> of the
 @fa<triggering_alternative>; the @fa<abortable_part> is never started.
 
-!corrigendum 9.8(3)
+!corrigendum 10.2.1(11)
+!comment The wording of AI-161 for 10.2.1(11) is omitted here. The changes are
+!comment placed into the conflict file.
+!comment We just put a dummy paragraph here:
 
-@drepl
-Each @i<task_>@fa<name> is expected to be of any task type; they need not all
-be of the same task type.
-@dby
-Each @i<task_>@fa<name> is expected to be of any task type or task interface
-type; they need not all be of the same type.
+!corrigendum 10.02.01(11/1)
+
+@dinsa
+If a @fa<pragma> Preelaborate (or @fa<pragma> Pure -- see below) applies to a
+library unit, then it is @i<preelaborated>. If a library unit is preelaborated,
+then its declaration, if any, and body, if any, are elaborated prior to all
+non-preelaborated @fa<library_item>s of the partition. The declaration and body
+of a preelaborated library unit, and all subunits that are elaborated as part
+of elaborating the library unit, shall be preelaborable. In addition to the
+places where Legality Rules normally apply (see 12.3), this rule applies also
+in the private part of an instance of a generic unit. In addition, all
+compilation units of a preelaborated library unit shall depend semantically
+only on compilation units of other preelaborated library units.
+@dinss
+The following rules specify which entities have @i<preelaborable initialization>:
 
-!corrigendum 9.9(1)
+!corrigendum J.09(3)
 
 @drepl
-For a @fa<prefix> T that is of a task type (after any implicit dereference),
-the following attributes are defined:
+Storage_Size may be specified for a task first subtype via an
+@fa<attribute_definition_clause>.
 @dby
-For a @fa<prefix> T that is of a task type or task interface type (after any
-implicit dereference), the following attributes are defined:
+Storage_Size may be specified for a task first subtype that is not
+an interface via an @fa<attribute_definition_clause>.
 
-!comment The wording of AI-251 for 12.5.5 is omitted here; as a new section,
-!comment we can't reference it. The changes are placed into the conflict file.
-!comment We just put a dummy paragraph here:
-!corrigendum 12.5.5(1)
-
-@dinsc
-The class determined for a formal interface type is the class of all
-interface types.
-
 !ACATS test
 
 Created ACATS tests (both B and C tests) for this feature.
@@ -5624,3 +5652,1232 @@
 
 ****************************************************************
 
+From: Tucker Taft
+Sent: Monday, May 9, 2005  3:55 PM
+
+I've thought of another way to explain the rule that you
+don't inherit limitness from interfaces.  The underlying
+rule about limitness is that if any component is limited,
+the enclosing type is necessarily limited, to avoid having
+equality or assignment "generalized" to apply to a limited
+component.  In several ways, extending a non-interface
+type is like having the parent type as a component.
+In  particular, equality and assignment pretty
+much treat the parent "part" as a component.  So
+if the parent type is limited, the extended type is
+necessarily limited, to avoid "generalizing" the equality
+and assignment to apply to this limited pseudo-component.
+
+On the other hand, extending an interface is *not* like
+having a component -- all that is inherited is a bunch
+of subprogram specs that must be overridden.  And in this
+case, limitedness is simply the absence of two "operators,"
+namely equality and ":=", and hence being a limited interface
+imposes no special burden on the extenders -- in fact, it
+imposes *less* of a burden than the typical type, since there
+is no inherited equality or assignment to worry about.
+
+Perhaps it is just rationalization, but it makes me feel
+even more like we made the right ultimate choice of associating
+the "inheritance" of limitness only with having a limited
+non-interface parent.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, May 9, 2005  4:15 PM
+
+I relatively recently read an article that talked about "object"
+encapsulation vs. "module" encapsulation.  It took me a while
+to understand the point, but the idea is that with "object"
+encapsulation, operations applied to one object don't have
+access to the innards of other objects (even of the same type).
+With "module" encapsulation, the encapsulation is associated
+with one or more types and the operations thereof, such that
+operations only have access to the innards of objects of
+a type associated with their module.   Module encapsulation
+provides information hiding, essentially compiler-enforced
+modularity, easing future maintenance by ensuring that
+it is easy to locate all the code that might depend on the
+details of the representation of a given type.
+
+It seems harder to understand the value of object encapsulation,
+until you start thinking about synchronization of access.
+Then suddenly, it is clear you want *object* encapsulation,
+not *module* encapsulation, to support synchronization of
+access in the presence of multitasking/multithreading.
+
+Interestingly, Ada distinguishes syntactically between
+*object* encapsulation, which is provided by task
+and protected types, and *module* encapsulation, which
+is provided by packages and private types.  For object encapsulation,
+the "privileged" operations are "inside" the object/type,
+whereas for module encapsulation, the "privileged" operations
+are inside the module, but "outside" the object/type.
+
+On the other hand, languages like Java, C++, Eiffel, etc.,
+put their "privileged" module-encapsulation operations
+inside the object/type, leaving no easy way to provide
+support for the kind of object encapsulation useful for
+synchronization.  Java provides built in support for
+object synchronization, but the syntactic constructs
+really don't give any very useful guarantees of exclusive
+access.  You can mark an operation "synchronized" in
+Java, but all that means is that it automatically gets
+a lock on the "prefix"/"this" object on call and
+releases it on return.  There is nothing that prevents
+someone from writing unsychronized operations that
+manipulate the innards of objects, nor anything that
+prevents a synchronized operation from manipulating
+the innards of objects other than the one that is locked!
+
+This all seems very interesting to me in terms of explaining
+why Ada doesn't put *all* the "privileged" operations "inside"
+the type.  From the very beginning of Ada, multitasking
+was a big deal, and the operations "inside" the type were
+those that needed *object* encapsulation.  The ones outside
+the type, but still inside the package, were the ones that
+supported "module" encapsulation, i.e. information hiding/modularity.
+
+So in retrospect, Ada seems very clever in supporting both
+"inside" and "outside" privileged operations, because that
+is *exactly* what you want to distinguish "object" encapsulation
+from "module" encapsulation.  Java, on the other hand, seems
+to have a completely *broken* synchronization model, since it
+provides no useful synchronization guarantees because it has
+no real support for "object" encapsulation  This is in part because
+Java (like most other O-O languages), "wasted" the syntactic
+encapsulation of operations inside a type on "module" encapsulation,
+leaving nothing obvious to do to represent object encapsulation.
+
+For what all that's worth... (might be a nice paper some day ;-).
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Monday, May 23, 2005  8:56 AM
+
+I would like to have the ARG's opinion on the following (thorny) issue
+that cropped up recently while  trying to put together the next draft of
+the reference manual.
+
+We now have task and protected tagged types, which are obtained by
+declaring a task or protected type with (synchronized or limited)
+interfaces as its progenitors, as in:
+
+	type Itf is synchronized interface;
+	procedure P (X : Itf; Y : Integer);
+
+	task type Tsk is new Itf with
+	   entry P (Y : Integer);
+	end Tsk;
+
+In this case, the type Tsk inherits a primitive subprogram P that is
+implemented by the entry P.   Fine, see AI 345 for details.
+
+Now unfortunately AI 345 doesn't say what happens when you derive from Tsk
+itself.  We said many  times that we didn't want to support extending task
+or protected objects because we didn't know how  to properly define the
+semantics of synchronization in this case.  So the first option we have
+is:
+
+1 - Make it illegal to derive from a tagged task or protected type.
+
+This may seem strange, but we have a precedent here: it is illegal to
+derive from a class-wide type.   Of course, rules would be needed to
+ensure that this check does not create privacy violations, but we  believe
+that this is feasible.
+
+However, there are cases where derivation is useful, notably to bring
+operations in the "right" scope or to complete a private type, e.g. by a
+type exported from an instantiation.  For instance:
+
+	generic
+	package Gen is
+	   task type Tsk is new Itf with
+	      entry P (Y : Integer);
+	   end Tsk;
+	end Gen;
+
+	package Pak is
+	   type Priv is limited private;
+	private
+	   package Inst is new Gen;
+	   type Priv is new Inst.Tsk ...; -- Would be nice.
+	end Pak;
+
+So our second option is:
+
+2 - Allow some form of derivation from a tagged task or protected type.
+
+Now what should such a derivation look like?  Tsk being a tagged type, we
+don't probably don't want a  derivation that would look like an untagged
+derivation, so it seems like the following is not a good  idea:
+
+	type Der is new Tsk; -- Don't want this.
+
+We went out of our way to make null extensions work more easily with
+functions precisely to solve the reexport problem for normal tagged types,
+so one possibility is:
+
+2a - Allow only a null extension when deriving from a tagged task or
+protected type.
+
+This would mean that the following would be legal:
+
+	type Der is new Tsk with null record;
+
+The type Der would get a new tag, and its inherited primitive operations
+could be overridden, and dispatching would happen as usual.
+
+But then it seems somewhat strange to special case a null extension, and
+also to extend a task with something that looks syntactically like a
+record.  At this point we are entering the realm of wild idea with:
+
+2b - Allow some elaborate form of extension when deriving from a tagged
+task or protected type: non-null record extension, new forms of extension
+specific to task and/or protected types, etc.
+
+Suggestions and comments welcome.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Monday, May 23, 2005  10:33 AM
+
+>Now unfortunately AI 345 doesn't say what happens when you derive from Tsk
+>itself.  We said many  times that we didn't want to support extending task
+>or protected objects because we didn't know how  to properly define the
+>semantics of synchronization in this case.
+
+I haven't seen a problem here, because I have been assuming that the
+semantics were similar to having a tagged type with a component of a
+task or protected type.  In other words, protected, task, and
+synchronized interfaces add additional magic wrappers to types which
+could be declared in Ada95.  (For example, you want
+Tagged_Task_Type'Terminated to map to
+Tagged_Task_Type.Task_Component'Terminated, and so on.)
+
+If you go with this solution, then components added to a protected
+tagged object are not directly protected. If the extension is private,
+the implementation can use say P and V operations that are part of the
+original protected object to provide protected semantics to these
+additional components.  (Or more likely, if the protected object has Get
+and Set operations, they can be extended to read or write the additional
+components, and the locking inherent in the protected object will
+protect the additional components as well.  Of course there is nothing
+to prevent the author of the extention from violating this semantic
+model with respect to the additional components.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, May 23, 2005  12:14 PM
+
+> I would like to have the ARG's opinion on the following (thorny) issue
+> that cropped up recently while  trying to put together the next draft of
+> the reference manual.
+
+Thanks, Pascal, for an excellent summary of the issues.
+I'm now less confused on this issue than I was.
+
+...
+> 1 - Make it illegal to derive from a tagged task or protected type.
+
+I could live with this.  But it seems like one of those annoying
+arbitrary restrictions Ada is always pestering me with.
+
+...
+> So our second option is:
+>
+> 2 - Allow some form of derivation from a tagged task or protected type.
+>
+> Now what should such a derivation look like?  Tsk being a tagged type, we
+> don't probably don't want a  derivation that would look like an untagged
+> derivation, so it seems like the following is not a good  idea:
+>
+> 	type Der is new Tsk; -- Don't want this.
+
+Agreed -- not that.
+
+> We went out of our way to make null extensions work more easily with
+> functions precisely to solve the reexport problem for normal tagged types,
+> so one possibility is:
+>
+> 2a - Allow only a null extension when deriving from a tagged task or
+> protected type.
+>
+> This would mean that the following would be legal:
+>
+> 	type Der is new Tsk with null record;
+>
+> The type Der would get a new tag, and its inherited primitive operations
+> could be overridden, and dispatching would happen as usual.
+
+I think I could live with this.  But are you saying that it's OK to
+override P on type Priv above?  If that's OK, then fine -- I just don't
+understand the ramifications.
+
+> But then it seems somewhat strange to special case a null extension, and
+> also to extend a task with something that looks syntactically like a
+> record.  At this point we are entering the realm of wild idea with:
+
+It doesn't bother me that null extension is a special case.
+Nor does it bother me (much) that we say "null record"
+when it's not a record.  If we started over, who knows? -- we might have
+used "with nothing;" instead of "with null record;" all over,
+but that's no big deal.
+
+> 2b - Allow some elaborate form of extension when deriving from a tagged
+> task or protected type: non-null record extension, new forms of extension
+> specific to task and/or protected types, etc.
+
+I am against these, especially at this late date.
+
+It is admittedly a wee bit odd that you can have a null extension but
+not a non-null extension.  Tough luck.  Null extensions are special.
+
+I've heard the idea that the "parent-as-component" model leads naturally
+to the idea that you can add components to tasks, and they're just
+unsynchronized components, like regular record components.  But I think
+that would lead to confusion on the part of users, who might not
+understand that model.  Anyway, that model has always struck me more as
+an implementation model than a semantic one.  Usually, when extending
+things, users are thinking "isa" and other more high-level concepts.
+
+That is, one might expect extension components to be somehow protected.
+
+----------------
+
+Summary: I guess I'm happy with either 1 or 2a.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, May 23, 2005  7:40 PM
+
+I agree with Bob on all points.  Hence, I prefer (1) or (2a).
+That is, disallow derivation, or allow null extensions (that is,
+"null record" extensions).  I see no problem in allowing overriding
+of primitives, though only for primitives that are *not* implemented
+by an entry/protected operation (since otherwise you would be
+violating the "no ambiguity" rule between primitives and
+entry/protected operations).
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, May 23, 2005  9:09 PM
+
+Bob replied to Pascal:
+
+...
+> > 1 - Make it illegal to derive from a tagged task or protected type.
+>
+> I could live with this.  But it seems like one of those annoying
+> arbitrary restrictions Ada is always pestering me with.
+
+This, BTW, is the "status quo"; AI-345 was written this way. And I *think*
+that all of the issues are properly dealt with at this point.
+
+> > This may seem strange, but we have a precedent here: it is illegal to
+> > derive from a class-wide type.   Of course, rules would be needed to
+> > ensure that this check does not create privacy violations, but we
+believe
+> > that this is feasible.
+> >
+> > However, there are cases where derivation is useful, notably to bring
+> > operations in the "right" scope or to complete a private type, e.g. by a
+> > type exported from an instantiation.  For instance:
+> >
+> > 	generic
+> > 	package Gen is
+> > 	   task type Tsk is new Itf with
+> > 	      entry P (Y : Integer);
+> > 	   end Tsk;
+> > 	end Gen;
+> >
+> > 	package Pak is
+> > 	   type Priv is limited private;
+> > 	private
+> > 	   package Inst is new Gen;
+> > 	   type Priv is new Inst.Tsk ...; -- Would be nice.
+> > 	end Pak;
+
+Yes, this case is worth looks at solutions for. The other use mentioned
+above "bring
+operations in the 'right' scope" has similar properties to a use clause, and
+should get the same amount of love and support. :-)
+
+> > So our second option is:
+> >
+> > 2 - Allow some form of derivation from a tagged task or protected type.
+> >
+> > Now what should such a derivation look like?  Tsk being a tagged type,
+we
+> > don't probably don't want a  derivation that would look like an untagged
+> > derivation, so it seems like the following is not a good  idea:
+> >
+> > 	type Der is new Tsk; -- Don't want this.
+>
+> Agreed -- not that.
+
+Strongly agree here.
+
+> > We went out of our way to make null extensions work more easily with
+> > functions precisely to solve the reexport problem for normal tagged
+types,
+> > so one possibility is:
+> >
+> > 2a - Allow only a null extension when deriving from a tagged task or
+> > protected type.
+> >
+> > This would mean that the following would be legal:
+> >
+> > 	type Der is new Tsk with null record;
+> >
+> > The type Der would get a new tag, and its inherited primitive operations
+> > could be overridden, and dispatching would happen as usual.
+>
+> I think I could live with this.  But are you saying that it's OK to
+> override P on type Priv above?  If that's OK, then fine -- I just don't
+> understand the ramifications.
+
+Yes, Pascal is proposing that overridings (and new operations) could be
+given. It would be hard to prevent them, and similar constructs are allowed
+(in most cases) for the parent type anyway.
+
+> > But then it seems somewhat strange to special case a null extension, and
+> > also to extend a task with something that looks syntactically like a
+> > record.  At this point we are entering the realm of wild idea with:
+>
+> It doesn't bother me that null extension is a special case.
+> Nor does it bother me (much) that we say "null record"
+> when it's not a record.  If we started over, who knows? -- we might have
+> used "with nothing;" instead of "with null record;" all over,
+> but that's no big deal.
+
+It does bother me, a lot. Making "null record" special decreases
+maintainability a lot, because adding a component now means the potential
+for piles of new errors. That means it requires far more thought than it
+used to.
+
+In particular, it pretty much trashes my personal workflow. Generally, when
+I have to declare a new extension, I will create the "infrastructure" first:
+empty type and subprogram declarations for everything. Then I get it to
+compile. That often can take most of a day with complicated parent types
+(with lots of functions and abstract operations). Only once it compiles will
+I start to implement anything; and only then will I consider if any
+extension components are needed. (At least half of the time, the initial
+answer is no, but that changes during implementation.)
+
+This flow will no longer work without modifications. The easiest fix is to
+adopt a rule that no null extensions are allowed unless there *never* will
+be an added component; every type has to contain a dummy component:
+   Dummy_Component_required_by_that_expletive_deleted_Tucker : Boolean;
+which can be deleted if a real component is needed.
+
+This (extremely ugly) possibility is why I eventually caved on this issue.
+
+However, if we now extend this to synchronized tagged types, we know are
+making it impossible to add additional components. That means that using
+such types is the same as painting yourself into a corner.
+
+Consider, for instance that you have a tagged protected type that comes from
+a library outside of your control:
+
+    type Protected_Queue is synchronized interface;
+    protected type Locked_Queue is ...
+
+Let's say that you now used that to declare an enhanced queue:
+
+    package PP is
+        type Better_Queue is new Protected_Queue with private;
+        procedure Wonderful_Operation (O : Better_Queue);
+    private
+        type Better_Queue is new Locked_Queue with null record;
+    end;
+
+All is fine. At a later point, someone realizes that Wonderful_Operation
+would be better implemented if each queue has a unique serial number. So we
+need to add:
+    Serial_Number : Natural := Serial.Get_Serial_Number;
+to each object. This component (which is write-once, and should be declared
+to be a constant, which Ada doesn't allow unfortunately) doesn't need to be
+protected. (This is true of a significant number of the components in Claw,
+for instance.)
+
+However, the only way to add this component is to either change the
+specification of this package to eliminate the visible interface, or to
+write a complete replacement for the Locked_Queue (so the component can be
+added inside of the PT, even though it doesn't need the serialization of a
+protected type).
+
+You can't add a wrapper type, because that type would not match the
+synchronized interface.
+
+This is such a massive change that it's likely to be impossible in a real
+system. (Implementing a second copy of a massive abstraction isn't a
+realistic possibility, and if the code makes any use at all of the fact that
+the type has the Protected_Queue interface, which seems likely, removing
+dependence on that seems impractical.)
+
+Virtually all of my OOP maintenance programming comes down to adding
+additional operations and components to types, so I expect this scenario to
+happen fairly often. (Presuming that interfaces get used at all.)
+
+Allowing all forms of record extension would at least avoid this latter
+problem. Of course, the model would have to be a component extension model,
+which admittedly is a but confusing.
+
+> > 2b - Allow some elaborate form of extension when deriving from a tagged
+> > task or protected type: non-null record extension, new forms of
+extension
+> > specific to task and/or protected types, etc.
+>
+> I am against these, especially at this late date.
+>
+> It is admittedly a wee bit odd that you can have a null extension but
+> not a non-null extension.  Tough luck.  Null extensions are special.
+
+Null extensions can't be special. Certainly not so special that using one
+paints you into a corner. At least interfaces allow don't allow operation
+bodies, so that there can be no need for components in them. But here, you
+probably need components, you just can't have them.
+
+Indeed, if this stands, I'll probably have to invent syntax/pragma for
+"non-special" null extensions (and an appropriate Restriction banning real
+null extensions) so that I don't have to carry around the space of dummy
+components, and so that there never is a maintenance problem.
+
+> I've heard the idea that the "parent-as-component" model leads naturally
+> to the idea that you can add components to tasks, and they're just
+> unsynchronized components, like regular record components.  But I think
+> that would lead to confusion on the part of users, who might not
+> understand that model.  Anyway, that model has always struck me more as
+> an implementation model than a semantic one.  Usually, when extending
+> things, users are thinking "isa" and other more high-level concepts.
+>
+> That is, one might expect extension components to be somehow protected.
+
+Fair enough. Then we should just retain the ban against extensions.
+
+> Summary: I guess I'm happy with either 1 or 2a.
+
+1 doesn't both me too much; but I can't live with 2a. A 2b that allowed
+unprotected extensions would be OK by me, but I can understand that people
+might be confused. (I think they'll be confused by synchronized interfaces
+in any case. :-)
+
+I'd be happy to solve this problem by dropping interfaces altogether. Every
+example I've seen for using them doesn't work out for some reason or other,
+and thus I think that users are more seduced by their promise than the
+reality. But I expect to get a lot less support for that than I will for the
+above...
+
+****************************************************************
+
+From: Alan Burns
+Sent: Tuesday, May 24, 2005  6:59 AM
+
+> Now unfortunately AI 345 doesn't say what happens when you derive from Tsk
+> itself.  We said many  times that we didn't want to support extending task
+> or protected objects because we didn't know how  to properly define the
+> semantics of synchronization in this case.  So the first option we have
+> is:
+>
+> 1 - Make it illegal to derive from a tagged task or protected type.
+
+
+This seems OK
+
+I'm a bit confused by the notion of a tagged task type?
+
+We have not been able to extend a task type before, have we?
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, May 24, 2005  7:59 AM
+
+> I'm a bit confused by the notion of a tagged task type?
+
+A task type is tagged if and only if it implements some interface type.
+I don't think we can change this rule.
+
+> We have not been able to extend a task type before, have we?
+
+No.  This is new in Ada 200X.
+
+In Ada 83 and 95, task types are always untagged.  You can always derive
+from them in the usual untagged way, without any extension.
+Now we have tagged task types.  When you derive from a tagged type,
+you always have to say "with <something>".  But that's not (currently)
+allowed for task types.  In other words, you are both required and
+forbidden from saying "with <something>".
+
+So the current situation is that if you choose to make your task type
+implement some interface, then you lose the ability to derive from that
+task type.  Unless we change the rules.
+
+****************************************************************
+
+From: Alan Burns
+Sent: Tuesday, May 24, 2005  8:24 AM
+
+> So the current situation is that if you choose to make your task type
+> implement some interface, then you lose the ability to derive from that
+> task type.  Unless we change the rules.
+>
+
+Thanks for this clarification. I am even more certain that we should
+prevent deriving from tagged task types. Extending task interfaces gives us
+the expressive power we need. Deriving in the untagged way from a
+task type is not a particularly useful feature, so happy to loose that
+if the task type comes via an interface.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, May 24, 2005  8:26 AM
+
+> ... The other use mentioned above "bring
+> operations in the 'right' scope" has similar properties to a use clause, and
+> should get the same amount of love and support. :-)
+
+Yes, this usage of derivation is similar in purpose to use clauses.
+We all know you're a use-o-phobe.  But there are use-o-philes,
+and there are people like me who are somewhere in between.
+
+I really think it's out of line to base language design decisions on
+such personal stylistic preferences, unless those preferences are
+pretty-much universal.  There are many people, including Tuck and me,
+who currently use the "bring into right scope" idiom.  Like I said,
+I can live without this capability for tagged task types, but it
+will definitely feel like an arbitrary restriction.
+
+> In particular, it pretty much trashes my personal workflow. ...
+
+Shrug.  So don't use the feature.  I don't see how a feature you don't
+use can hurt you as a user (other than the usual fact that your compiler
+vendor wastes energy on something you don't need -- and in this case you
+are the compiler vendor).
+
+Or use a coding convention that says "with null record" means there are
+no new components and never will be, whereas "with record null; end
+record" means you're planning to stick in some new components one day.
+
+>     Serial_Number : Natural := Serial.Get_Serial_Number;
+> to each object. This component (which is write-once, and should be declared
+> to be a constant, which Ada doesn't allow unfortunately) doesn't need to be
+> protected. (This is true of a significant number of the components in Claw,
+> for instance.)
+
+Constant record components are called "discriminants".  ;-)
+
+Which leads to the question: if we allow "with null record", will we
+allow discriminants?  I.e. will this be allowed in proposal 2a:
+
+    generic
+    package Gen is
+       task type Tsk is new Itf with
+          entry P (Y : Integer);
+       end Tsk;
+    end Gen;
+
+    package Pak is
+       type Priv is limited private;
+    private
+       package Inst is new Gen;
+-->    type Priv(Serial_Number : Natural := Get_Serial_Number) is -- Legal?
+           new Inst.Tsk with null record;
+    end Pak;
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Tuesday, May 24, 2005  12:57 PM
+
+My feeling is that it's not worth allowing discriminants to be added
+in proposal 2a.  I think it could be creating extra implementation
+work for too little benefit.  It also seems that users are going to
+be frustrated that they can add discriminants but not other components.
+
+I'm starting to lean toward proposal 1, despite the restrictiveness.
+That would at least leave the door open for adding more general
+extensions of tagged task types in the future once some experience
+is gained with the feature, without locking us into "with null record"
+syntax, which might later look like a wart if we decided to go with
+something else.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, May 24, 2005  1:45 PM
+
+> > In particular, it pretty much trashes my personal workflow. ...
+>
+> Shrug.  So don't use the feature.  I don't see how a feature you don't
+> use can hurt you as a user (other than the usual fact that your compiler
+> vendor wastes energy on something you don't need -- and in this case you
+> are the compiler vendor).
+>
+> Or use a coding convention that says "with null record" means there are
+> no new components and never will be, whereas "with record null; end
+> record" means you're planning to stick in some new components one day.
+
+That doesn't work, because it would still cause all of the errors when a
+component is added. A "null extension" is a technical term, and it includes
+both forms.
+
+...
+> Constant record components are called "discriminants".  ;-)
+>
+> Which leads to the question: if we allow "with null record", will we
+> allow discriminants?
+
+No; the definition of "null extension" (in 3.9.1(4.1/2), look in the fine
+index :-) is clear that there are no added discriminants. That's necessary
+for the current use of the feature (which is to require that the compiler
+build wrappers for any functions). I would presume that we'd reuse the same
+term, because it would be too confusing to have two very similar concepts.
+
+So, you can't have any discriminants, either.
+
+I don't think a discriminant is an appropriate way to model this anyway;
+discriminants are type parameters intended for the user of the type. You
+could hide them in the private part, but that wouldn't work if there were
+any real discriminants on the type that you did want to expose.
+Discriminants also get in the way of assignment (not a problem here, but one
+I frequently run into), since objects typically are constrained (and you
+generally don't want that for these sorts of components).
+
+****************************************************************
+
+From: Stephen Michell
+Sent: Tuesday, May 24, 2005  2:28 PM
+
+This represents a significant issue. Discriminants were added for Tasks and
+protected types to permit per-object customization, such as priorities,
+self-referential or access- to-object capabilities that Ada87 had essentially
+prohibited. If tasks derived from interfaces don't have the same capabilities
+then we will be back to trying to develop all sorts of workarounds as we did
+15-20 years ago.
+
+It didn't make sense to derive from a task type in Ada87, but it does in Ada95
+so that you can specialize the discriminants. Again, I think that this is a
+capability that we need to promulgate to tasks derived from interface types.
+
+I guess this means that I think that we need to include discriminants and that
+we cannot forbid derivation in the sense of "with null record" for tasks and
+for protected types.
+
+I'm not sure if Bob means that he thinks that we should permit more arbitrary
+task extensions, but before anyone goes down that road, read the Extensible
+Protected type article that we wrote for TOPLAS a few years ago (Wellings,
+myself and a host of others) and the AI on EPT (don't have the reference here).
+Tasking is much worse because tasks can execute accepts on an entry from many
+code blocks and in any arbitrary combination.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, May 24, 2005  2:56 PM
+
+> I'm not sure if Bob means that he thinks that we should permit more arbitrary task
+> extensions...
+
+No, I was not advocating that.  I was simply asking a question,
+and I'm happy with the answers given by Gary and Randy.
+
+****************************************************************
+
+From: Tuillo Vardanega
+Sent: Wednesday, May 25, 2005  8:21 AM
+
+Pascal's issue was very clearly illustrated.
+
+From my standpoint, I am for alternative 1) which I
+view as the cleanest by far, because it puts a safe fence
+to a problematic issue and defers any route to possible
+task / protected type extensions to more solid reflection
+(which would obviously be needed).
+
+I view alternative 2a) as possible, though Randy seems
+to argue against it, but I'd consider it only if someone
+could show that it brought more value than hassle.
+Finally, I oppose to 2b), which sounds like unthinkable
+at this point in time.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, May 27, 2005  10:41 AM
+
+> 1 - Make it illegal to derive from a tagged task or protected type.
+>
+> 2 - Allow some form of derivation from a tagged task or
+> protected type.
+>
+> 2a - Allow only a null extension when deriving from a tagged
+> task or protected type.
+>
+> 2b - Allow some elaborate form of extension when deriving
+> from a tagged task or protected type: non-null record
+> extension, new forms of extension specific to task and/or
+> protected types, etc.
+
+Based on the feedback received so far, I am going to make the decision to
+go for option 1.
+
+It seems that the limitation is acceptable, and can always be revised
+later if it turns out to be problematic in practice.  Also this is the
+conservative option: if we were to allow some form of extension at this
+late stage, there would be a risk of making the wrong choices, and we
+would have to live with the consequences.
+
+If anyone disagrees with this decision I'll be happy to have the topic
+discussed in York, but I'll insist on having an AI describing an
+alternative (or several alternatives) before the meeting.
+
+Randy: You and I will privately work out the wording adjustments needed to
+implement this option.  They are certainly rather minor.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, June 6, 2005  12:36 PM
+
+I'm using draft 11.8 of the [A]ARM.
+
+3.9.4(5/2):
+
+5/2   {AI95-00345-01} An interface with the reserved word limited, task,
+protected, or synchronized in its definition is termed, respectively, a
+limited interface, a task interface, a protected interface, or a synchronized
+interface. In addition,{interface (synchronized) [partial]}
+{interface (protected) [partial]} {interface (task) [partial]}
+{interface (limited) [partial]} {interface (nonlimited) [partial]}
+{synchronized interface} {protected interface} {task interface}
+{limited interface} {nonlimited interface} all task and protected interfaces
+are synchronized interfaces, and all synchronized interfaces are limited
+interfaces. A view of an object that is of a task interface type (or of a
+corresponding class-wide type) is a task object. Similarly, a view of an
+object that is of a protected interface type (or of a corresponding class-wide
+type) is a protected object.
+
+Is a task interface type a task type?  Should it be?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, June 6, 2005  7:10 PM
+
+I would say "no, a task interface is *not* a task type."
+This is roughly analogous to saying an interface type
+is not a record type.  In my attempt to re-draw
+the task hierarchy, I put interfaces off in their own
+branch, which I think is probably wise.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, June 6, 2005  9:21 PM
+
+You mean "type hierarchy". And I hope that you think your own work is wise.
+:-)
+
+But I tend to agree as well. I believe we added "or task interface" to a
+number of places where task types were required for this reason.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, June 7, 2005  3:28 AM
+
+> Is a task interface type a task type?  Should it be?
+
+I don't think that it makes a big difference, but we decided that
+interfaces are not record/protected/task types.  The wording was crafted
+with that model in mind.  Unless we discover that it leads to actual
+problems, I suggest to stick to this model.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, June 7, 2005  5:44 AM
+
+9.7.2(3.2/2) has, in draft 11:
+
+"If a procedure_call_statement is used for a procedure_or_entry_call, the
+procedure_name or procedure_prefix of the procedure_call_statement shall
+denote an entry renamed as a procedure, a formal subprogram, or (a view
+of) a primitive subprogram of a limited interface whose first parameter is
+a controlling parameter (see 3.9.2)."
+
+I find this rule strange.  Obviously its purpose is to disallow the use of
+a "normal" procedure in a timed entry call.  However, it doesn't (and
+cannot) meet that goal because:
+
+1 - a primitive subprogram of a limited interface could very well be
+overridden by a normal procedure.
+2 - since a formal subprogram is allowed, it is possible to use a
+Goodenough-like trick to call a normal procedure by passing it to a
+generic.
+
+There is no real definitional problem, but it is strange to have a rule
+that can easily be circumvented.  What should we do here?  The options
+that come to mind include:
+
+1 - Leave it as is.
+
+2 - Remove the restriction entirely, anything goes.  The restriction is
+largely methodological anyway, so I don't think it would create any more
+implementation difficulties.
+
+3 - Make the restriction more stringent, i.e. only allow primitive
+subprograms of a limited interface, since this is the important new
+capability.  I am told by one implementer who is sharing generics that
+formal subprograms might be problematic, so this option may ease
+implementations.
+
+4 - Use a runtime check to ensure that the call actually executes an
+entry, not a normal procedure.
+
+5 - Other ideas?
+
+As usual, comments and feedback welcome.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, June 7, 2005  7:36 AM
+
+I vote to leave it as is.  From my perspective,
+the main purpose is to catch cases where it is
+"obvious" the call cannot possibly involve
+an entry call.  These are the cases where the
+programmer couldn't possibly have meant
+what they wrote.  I don't see it as a methodological
+restriction, I see it as catching errors.
+
+In the cases permitted, there is a legitimate
+possibility the name will denote an entry at run-time, and
+so it is possible the programmer meant what they wrote.
+If we disallow any of these cases, we *are* creating
+a methodological restriction.
+
+****************************************************************
+
+From: Alan Burns
+Sent: Tuesday, June 7, 2005  8:16 AM
+
+I agree - no run-time check please
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, June 7, 2005  2:06 PM
+
+> I vote to leave it as is.  From my perspective,
+> the main purpose is to catch cases where it is
+> "obvious" the call cannot possibly involve
+> an entry call.  These are the cases where the
+> programmer couldn't possibly have meant
+> what they wrote.  I don't see it as a methodological
+> restriction, I see it as catching errors.
+
+What error is getting caught here? Sure, it's a long-winded way to write a
+call, but it seems harmless.
+
+> In the cases permitted, there is a legitimate
+> possibility the name will denote an entry at run-time, and
+> so it is possible the programmer meant what they wrote.
+> If we disallow any of these cases, we *are* creating
+> a methodological restriction.
+
+I think it is a good idea to always expect that the programmer meant what
+they wrote. :-)
+
+Anyway, I don't mind the complication on interfaces too much, because the
+rather substantial overhead only is incurred if you use an interface. But
+once you put it on formal procedures, *every* formal procedure will have to
+carry that substantial overhead because the actual *might* be an entry and
+the formal *might* be used as an entry (a combination that will never happen
+in practice). That's especially bad for generic iterators, which otherwise
+is a case where universal code sharing really shines.
+
+I do agree that a runtime check doesn't seem to be warranted; it doesn't
+help implementations or users in any significant way.
+
+BTW, the rule as written does not allow renames of formal subprograms to be
+used as entries. So it needs even more exceptions and complications to meet
+Tucker's principles of disallowing *only* subprograms that could never be an
+entry. I have to wonder if it is worth it.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, June 7, 2005  3:44 PM
+
+> What error is getting caught here? Sure, it's a long-winded why to write a
+> call, but it seems harmless.
+
+The programmer meant to be calling an entry, and by mistake
+called a procedure with a similar name.
+
+>>In the cases permitted, there is a legitimate
+>>possibility the name will denote an entry at run-time, and
+>>so it is possible the programmer meant what they wrote.
+>>If we disallow any of these cases, we *are* creating
+>>a methodological restriction.
+>
+> I think it is a good idea to always expect that the programmer meant what
+> they wrote. :-)
+
+Really?  Then let's drop all the "B" tests from the ACATS... ;-)
+
+> Anyway, I don't mind the complication on interfaces too much, because the
+> rather substantial overhead only in incurred if you use an interface. But
+> once you put it on formal procedures, *every* formal procedure will have to
+> carry that substantial overhead because the actual *might* be an entry and
+> the formal *might* be used as an entry (a combination that will never happen
+> in practice). That's especially bad for generic iterators, which otherwise
+> is a case where universal code sharing really shines.
+
+You seem to be arguing both sides of the coin here.  Do you
+want to allow it on *all* procedures?  That won't solve
+this generic formal subprogram problem (unless, gasp,
+we allow it on all subprograms *other than* formal subprograms).
+
+In any case, you are right, it will require an additional
+boolean in your instance descriptor every time there is
+a formal subprogram.  That seems pretty onerous.
+On the other hand, it seems downright unfriendly to
+allow it on primitive procedures of an interface, and not
+allow it on procedures that are visibly renames of entries.
+That would look really weird to someone coming "new"
+to Ada 2006.
+
+I guess I could handle allowing it only on entries (visibly)
+renamed as procedures and on primitives of limited interfaces.
+This would be one of the rare cases where we treat generic
+formal subprograms and renames differently, but so be it.
+I agree that adding run-time burden to every instantiation
+with a formal generic procedure seems overly burdensome.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, June 7, 2005  5:38 PM
+
+> You seem to be arguing both sides of the coin here.  Do you
+> want to allow it on *all* procedures?  That won't solve
+> this generic formal subprogram problem (unless, gasp,
+> we allow it on all subprograms *other than* formal subprograms).
+
+Just trying to look at all sides of an issue. I might be wrong, you know
+:-), especially if I don't do that.
+
+> In any case, you are right, it will require an additional
+> boolean in your instance descriptor every time there is
+> a formal subprogram.  That seems pretty onerous.
+
+Huh? It would require at a minimum a totally separate thunk to support
+calling entries (entries and subprograms are called very differently).
+Moreover, a wrapper is required because of representation issues and because
+of up-level addressing (that's true of all subprograms). Since it is legal
+to call any old procedure this way, that wrapper would have to be
+constructed for *every* formal subprogram. So there is a substantial impact
+in code size. (The wrapper for ordinary formal subprograms is pretty large
+already.)
+
+I'm unconvinced that one thunk would do the job (for either case), so it's
+possible that multiple thunks (for the different kinds of calls) could be
+needed.
+
+There would be some runtime overhead as well, even when this isn't used (to
+set up pointers and other data for these various thunks in the instantiation
+descriptor), but I'll concede that the major expense is in space and in
+implementation complexity.
+
+> On the other hand, it seems downright unfriendly to
+> allow it on primitive procedures of an interface, and not
+> allow it on procedures that are visibly renames of entries.
+> That would look really weird to someone coming "new"
+> to Ada 2006.
+
+I'm not quite sure why that would be weird. What's weird is reusing
+procedures for this in the first place (something started by Ada 83), rather
+than having a separate set of entry operations. It certainly seems better to
+avoid mixing the concepts.
+
+Once you have the oddity, it seems weird (to me) to not unify them
+completely, treating entries and procedures as interchangable. (While that
+wouldn't help the implementation at all, it would seem to simplify the
+language.) Certainly, that's what *I* thought we'd decided to do.
+
+> I guess I could handle allowing it only on entries (visibly)
+> renamed as procedures and on primitives of limited interfaces.
+> This would be one of the rare cases where we treat generic
+> formal subprograms and renames differently, but so be it.
+> I agree that adding run-time burden to every instantiation
+> with a formal generic procedure seems overly burdensome.
+
+Yes, I see both sides here, so I'm torn.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, June 7, 2005  5:40 PM
+
+> I guess I could handle allowing it only on entries (visibly)
+> renamed as procedures and on primitives of limited interfaces.
+> This would be one of the rare cases where we treat generic
+> formal subprograms and renames differently, but so be it.
+
+I would prefer to keep the rules for formal subprograms and renames the
+same.  It seems like an important compiler-simplifying principle.
+
+> I agree that adding run-time burden to every instantiation
+> with a formal generic procedure seems overly burdensome.
+
+I agree.  So disallow the entry case.  Is it useful?  The formal subp
+case seems more useful than the renames...
+
+Please ignore this comment if I am confused.  ;-)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, June 7, 2005  6:06 PM
+
+> Please ignore this comment if I am confused.  ;-)
+
+I know I'm confused, because I'm arguing both sides. :-)
+
+But Ada 95 doesn't have a way to rename entries and still be able to use
+them as entries. This gives us part of that missing capability (part,
+because we don't allow requeuing on procedures of any kind -- that's just
+too hard to determine a meaning for).
+
+I think either case is about equally useful, but neither have much to do
+with calling operations of task or protected interfaces, which is the real
+deal here. And, as Pascal points out, you could use an abstract formal
+subprogram (Bob probably hasn't read about those yet) to pass in a
+dispatching interface routine to a generic -- it would be a dispatching
+operation of an interface type -- so there would still be a way to
+accomplish what is needed. Indeed, that's the only way to pass a dispatching
+routine into a generic, so "regular" formal_subprograms are pretty much
+irrelevant for the basic capability.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, June 7, 2005  6:48 PM
+
+> ... And, as Pascal points out, you could use an abstract formal
+> subprogram (Bob probably hasn't read about those yet)
+
+Actually, I was so confused by something in chaps 3/4, that I peeked
+ahead and looked at those.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, June 8, 2005  3:21 AM
+
+> I would prefer to keep the rules for formal subprograms and
+> renames the same.  It seems like an important
+> compiler-simplifying principle.
+
+Absolutely.  Making the rules slightly different to address an obscure
+cornercase is a horrible idea.  Wearing my compiler hat, the last thing I
+want to do is to revisit our implementation of actual/formal subprogram
+matching to make it work much-like-a-renaming-but-not-quite.
+
+> > I agree that adding run-time burden to every instantiation with a
+> > formal generic procedure seems overly burdensome.
+>
+> I agree.  So disallow the entry case.  Is it useful?  The
+> formal subp case seems more useful than the renames...
+
+Renaming an entry as a procedure is certainly not an important capability
+in my view.  Few users even knew about.  One could argue that it was not
+properly supported in Ada 83 or 95, since you couldn't call it in contexts
+that required an entry, even though the compiler knew darn well that the
+actual callable entity is an entry.
+
+If we can integrate it better in Ada 05, fine, but if it comes with any
+complexity in terms of language definition or implementation, forget it.
+
+The important capability (and the reason why we are discussing this in the
+first place) are synchronized interfaces and tagged task/protected types.
+I am in favor of allowing only those in contexts that want an entry call.
+This provides all the needed flexibility, without introducing undue
+complexity for generics and renamings.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Friday, June 10, 2005  2:06 PM
+
+Pascal Leroy wrote:
+
+>9.7.2(3.2/2) has, in draft 11:
+>
+>"If a procedure_call_statement is used for a procedure_or_entry_call, the
+>procedure_name or procedure_prefix of the procedure_call_statement shall
+>denote an entry renamed as a procedure, a formal subprogram, or (a view
+>of) a primitive subprogram of a limited interface whose first parameter is
+>a controlling parameter (see 3.9.2)."
+>...
+>There is no real definitional problem, but it is strange to have a rule
+>that can easily be circumvented.  What should we do here?  The options
+>that come to mind include:
+>...
+>5 - Other ideas?
+
+Hmm.  The missing option seems to me to be allow the workarounds, but
+define the result as being that the subprogram is always called with no
+time-out or delay.
+
+The restriction seems wise for methodological reasons.  It outlaws
+something which is clearly a programming error.  But it also seems wrong
+to make implementors go to a lot of work to do a check which is not
+wanted by the implementor of the (non-reserved word) interface, and
+which would be viewed as actively harmful by a user of the abstraction
+or generic.
+
+It would help to give an example.  Suppose some implementations of an
+abstraction are local and always available.  Other implementations may
+have to allow for some subsystem to be turned off or even not installed
+.  A typical situation that I would see in the embedded world would have
+three non-real-time calls for all potentially present subsystems,
+basically "Are you there?" (AYT)  "Turn yourself on." (TYO) and "Are you
+ready?" (AYR)  During system initialization, you would normally call
+most of the TYO entries, subject to a short time out, then call TYO if
+the device is present, and then wait on the AYR calls in no particular
+order for the devices that were present.  Obviously for muntions stores,
+you might want to do the AYT call, but you definitely want to delay the
+other two. ;-)  The problem of course is that you can attach some
+devices such as a FLIR pod (forward looking infra-red) to a munitions
+hard point....
+
+But that is getting off topic.  The point is that you would have a
+generic interface where some subsystems are always present and powered
+if the processor is, and others calls need to be 'wrapped' in a time-out
+to allow the system to initialize if that subsystem is not present.
+This is not restricted to embedded systems, your PC does the same thing
+at boot-time.
+
+How difficult is this for implementors?  Not very.  Worst case, when an
+entry is implemented by a subprogram, the implementation provides an
+entry-like wrapper that calls the subprogram.  Of course, programmers
+who need the non-entry calls to be fast will check to see which
+compilers do the "obvious" optimization of bypassing the whole
+timed-entry baggage.  My guess is that most compilers will 'get it
+right' in simple cases, but the implementors and programmers will
+disagree about what makes a particular case simple.
+
+****************************************************************

Questions? Ask the ACAA Technical Agent