CVS difference for ais/ai-00345.txt

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

--- ais/ai-00345.txt	2004/01/08 04:16:39	1.5
+++ ais/ai-00345.txt	2004/01/23 01:26:41	1.6
@@ -1,4 +1,4 @@
-!standard  3.04.03    (00)                             03-12-14  AI95-00345/02
+!standard  3.04.03    (00)                             03-01-22  AI95-00345/03
 !class amendment 03-08-07
 !status work item 03-09-28
 !status received 03-06-12
@@ -8,11 +8,17 @@
 
 !summary
 
-Protected and Task interfaces are proposed. A protected or task
-type may specify one or more interfaces as ancestors. The synchronizing
-operations of these interfaces are inherited by the protected or task type.
-If the operations are declared abstract in the interface, they must be
-overridden in the inheriting type.
+Protected and Task interfaces are proposed. A protected or task type may
+specify one or more interfaces as ancestors. The synchronizing
+operations (entries and protected subprograms) of these interfaces are
+inherited by the protected or task type. If the operations are declared
+abstract in the interface, they must be overridden in the inheriting
+type.
+
+To integrate this feature with tagged interface types, we allow
+task and protected types/interfaces to be derived from
+"normal" limited interfaces. (This added capability is not
+essential, and could be dropped if it overburdens the proposal.)
 
 !problem
 
@@ -25,7 +31,62 @@
 
 !proposal
 
+(See wording.)
+
+!wording
+
+NOTE: This presumes AI-251 ("normal" interface types). We will
+identify where we are referring to AI-251 wording.
+
+Modify 3.4(4):
+
+  Class-wide types
+      Class-wide types are defined for (and belong to) each derivation
+      class rooted at a tagged {or interface} type (see 3.9 {and 3.9.4}) ...
+
+Modify 3.9(13):
+
+    For every subtype S of a tagged {or interface} type T (specific or
+    class-wide), the following attribute is defined:
+
+Replace 3.9.3(1-2) with:
+
+    An abstract type is a type intended for use as an ancestor of
+    other types, but which is not allowed to have objects of its own.
+
+        Static semantics
+
+    Interface types (see 3.9.4) are abstract types. In addition, a
+    tagged type that has the reserved word abstract in its declaration
+    is an abstract type. The class-wide type (see 3.4.1) rooted at an
+    abstract type is not itself an abstract type.
+
+        Legality Rules
+
+    Only a tagged type shall have the reserved word abstract in its
+    declaration.
+
+In the wording of AI-251:
+
+  Modify 3.9.4(1):
+
+    An interface type is an abstract [tagged] type intended for use in
+    providing a restricted form of multiple inheritance. A tagged type
+    may be derived from multiple interface types. {A task or protected
+    type may be derived from multiple limited interface types. Limited
+    interface types that are specifically for use in defining task or
+    protected types may also be defined (see 9.1 and 9.4).}
+
+  Modify 3.9.4(3):
+
+    An interface type (also called an "interface") {defined by an
+    interface_type_definition} is a specific abstract tagged type [that
+    is defined by an interface_type_definition].
+
+[end of AI-251-relative modifications]
+
 Add after 6.3.1(24):
+
     Two subprograms or entries are type conformant (respectively mode
     conformant, subtype conformant, or fully conformant) if their profiles are
     type conformant (respectively mode conformant, subtype conformant, or fully
@@ -34,24 +95,52 @@
     Two entry families are subtype conformant if their profiles are subtype
     conformant and their entry index subtypes match statically.
 
+In the wording of AI-251:
+
+  Modify 8.3(9/1):
+
+    ... The only declarations that are overridable are the implicit
+    declarations for predefined operators[ and]{,} inherited primitive
+    subprograms{, inherited abstract entries and entry families, and inherited
+    abstract or null protected subprograms}. ...
+
+  Modify 8.3(in part of replacement for para 13):
+
+  - If all are null procedures or abstract subprograms{ (possibly protected),
+    entries, or entry families}, then any null procedure overrides all
+    abstract subprograms; if more than one homograph remains that is not
+    thus overridden, then one is chosen arbitrarily to override the
+    others.
+
+  Modify 8.3(26/1 part 2):
+
+    If two or more homographs are implicitly declared at the same place
+    {and there is no non-overridable declaration that overrides them}
+    then at most one shall be a non-null non-abstract subprogram. If all
+    are null or abstract {subprograms, entries, or entry families}, then
+    all of the null subprograms shall be fully conformant with one
+    another. If all are abstract, then all of the subprograms{, entries,
+    or entry families} shall be fully conformant with one another.
+
+[end of AI-251-relative modifications]
+
 Add to the end of 9.1(1):
 
-	A task_interface_declaration declares a task interface type, specifying
-	entries or entry families that must be provided by any task type derived
-	from the interface.
+    A task_interface_declaration declares a task interface type, specifying
+    entries or entry families that shall be provided by any task type derived
+    from the interface.
 
 Change 9.1(2) to:
 
   task_type_declaration ::=
     TASK TYPE defining_identifier [known_discriminant_part] [IS
-      [NEW task_interface_subtype_mark {AND task_interface_subtype_mark} WITH]
+      [NEW interface_list WITH]
       task_definition];
 
-Add after 9.1(5/1) to:
+Add after 9.1(5/1):
 
   task_interface_declaration ::=
-    TASK INTERFACE defining_identifier IS
-      [NEW task_interface_subtype_mark {AND task_interface_subtype_mark} WITH]
+    TASK INTERFACE defining_identifier IS [NEW interface_list WITH]
       task_interface_definition;
 
   task_interface_definition ::=
@@ -60,56 +149,74 @@
 
 Change 9.1(7) to:
 
-	If a task_identifier appears at the end of a task_definition{,
-	task_interface_definition,} or task_body, it shall repeat the
-	defining_identifier.
+    If a task_identifier appears at the end of a task_definition{,
+    task_interface_definition,} or task_body, it shall repeat the
+    defining_identifier.
 
 Add after 9.1(8):
-
-    A task_interface_subtype_mark shall denote a task interface type.
 
-    If a task_type_declaration includes one or more
-    task_interface_subtype_marks, then each abstract entry (or entry
-    family) inherited by the task type shall be overridden with a subtype
-    conformant entry_declaration in the visible part of the task_type_declaration.
-
-    If a task_interface_declaration includes one or more task_interface_subtype_marks,
-    then if an abstract entry or entry family of a named task interface type has the
-    same identifier as an abstract entry or entry family of some other named
-    task interface type, or an abstract entry or entry family declared within the
-    task_interface_declaration, then:
-       - neither or both shall be an abstract entry family
+    Each interface_subtype_mark of an interface_list appearing within a
+    task_type_declaration or a task_interface_declaration shall denote a
+    limited interface type -- it may be a task interface type; it
+    shall not be a protected interface type.
+
+    If a task_type_declaration includes an interface_list, then each
+    abstract entry or entry family inherited by the task type shall be
+    overridden with a subtype conformant entry_declaration within the
+    task_type_declaration. If a task_interface_declaration includes an
+    interface_list and an abstract_entry_declaration of the
+    task_interface_definition overrides an inherited entry or entry
+    family, the explicitly declared entry or entry family shall be
+    subtype conformant with the inherited entry or entry family.
 
 Add after 9.1(9.1/1):
 
-	A task_interface_definition defines a task interface type and its first subtype.
-	The list of abstract_entry_declarations is the visible part of the
-	task_interface_declaration.  For each abstract_entry_declaration, a task interface
-	type has an abstract entry or entry family.  In addition, if the enclosing
-	task_interface_declaration includes one or more task_interface_subtype_marks,
-	the task interface type is derived from each named task interface, and it inherits
-	each of the abstract entry or entry families of the named interface.
+    A task_interface_definition defines a task interface type and its
+    first subtype. A task interface type is a limited interface type
+    (see 3.9.4). The list of abstract_entry_declarations is the visible
+    part of the task_interface_declaration.
+
+    If a task_type_declaration includes an interface_list, the task type
+    is derived from each interface named in the interface_list.
+    Similarly, if a task_interface_declaration includes an
+    interface_list, the task interface type is derived from each
+    interface named in the interface_list.
 
-	If a task_type_declaration includes one or more task_interface_subtype_marks,
-	the task type is derived from each named task interface.
+Add after 9.1(12/1):
 
-	If a task_inderface_declaration
+    The elaboration of a task_interface_declaration elaborates the
+    task_interface_definition. The elaboration of a
+    task_interface_definition creates the task interface type and its
+    first subtype; it also includes the elaboration of the
+    abstract_entry_declarations in the given order.
+
+Add to the end of 9.4(1):
+
+    A protected_interface_declaration declares a protected interface
+    type, specifying protected operations that are to be available for
+    any protected type derived from the interface.
 
+Change 9.4(2) to:
 
-Add after 9.1(12/1):
+  protected_type_declaration ::=
+    PROTECTED TYPE defining_identifier [known_discriminant_part] IS
+      [NEW protected_interface_name {AND protected_interface_name}
+        WITH] protected_definition;
 
-    The elaboration of a task_interface_declaration elaborates the
-    task_interface_definition. The elaboration of a task_interface_definition
-    creates the task interface type and its first subtype; it also includes the
-    elaboration of the abstract_entry_declarations in the given order.
+Change 9.4(5/1) to:
+
+  protected_operation_declaration ::= subprogram_declaration
+    | null_procedure_declaration
+    | entry_declaration
+    | aspect_clause
 
+Add after 9.4(6):
 
   protected_interface_declaration ::=
     PROTECTED INTERFACE defining_identifier IS
-      [NEW protected_interface_name {AND protected_interface_name} WITH]
+      [NEW limited_interface_subtype_mark {AND protected_interface_name} WITH]
       protected_interface_definition;
 
-
   protected_interface_definition ::=
       {protected_interface_item}
     END [protected_identifier]
@@ -118,42 +225,71 @@
     | null_procedure_declaration
     | abstract_entry_declaration
 
-  protected_type_declaration ::=
-    PROTECTED TYPE defining_identifier [known_discriminant_part] IS
-      [NEW protected_interface_name {AND protected_interface_name} WITH] protected_definition;
+Change 9.4(9) to:
 
-  protected_operation_declaration ::= subprogram_declaration
-    | null_procedure_declaration
-    | entry_declaration
-    | aspect_clause
+    If a protected_identifier appears at the end of a protected_definition{,
+    protected_interface_definition,} or protected_body, it shall repeat the
+    defining_identifier.
+
+Add after 9.4(10):
+
+    Each interface_subtype_mark of an interface_list appearing within a
+    protected_type_declaration or a protected_interface_declaration
+    shall denote a limited interface type -- it may be a protected interface
+    type; it shall not be a task interface type.
+
+    If a protected_type_declaration includes an interface_list, then
+    each abstract entry, abstract entry family, and abstract protected
+    subprogram inherited by the protected type shall be overridden with
+    a subtype conformant protected_operation_declaration within the
+    protected_type_declaration. If a protected_interface_declaration
+    includes an interface_list and a protected_interface_item of the
+    protected_interface_definition overrides an inherited entry, entry
+    family, or protected subprogram, the explicitly declared entity
+    shall be subtype conformant with the inherited entity.
+
+Modify 9.4(11):
+
+    A protected_interface_definition defines a protected interface type
+    and its first subtype. A protected interface type is a limited
+    interface type (see 3.9.4). The list of protected_interface_items
+    is the visible part of the protected_interface_declaration.
+
+    If a protected_type_declaration includes an interface_list, the
+    protected type is derived from each interface named in the
+    interface_list. Similarly, if a protected_interface_declaration
+    includes an interface_list, the protected interface type is derived
+    from each interface named in the interface_list.
+
+Add after 9.4(13):
+
+    The elaboration of a protected_interface_declaration elaborates the
+    protected_interface_definition. The elaboration of a
+    protected_interface_definition creates the protected interface type
+    and its first subtype; it also includes the elaboration of the
+    protected_interface_items in the given order.
+
+Add after 9.5.2(2):
 
   abstract_entry_declaration ::=
-    ENTRY defining_identifier [(discrete_subtype_definition)] parameter_profile IS ABSTRACT;
+    ENTRY defining_identifier [(discrete_subtype_definition)]
+      parameter_profile IS ABSTRACT;
 
-As with "normal" interfaces, a "concrete" type that inherits from
-an interface must override all abstract operations, but may inherit
-null procedures. We have not proposed null entries, since it is unclear
-what would be the barriers for those (True or False) or how they would
-fit into a task body (no accept statement?).
+Modify 9.5.2(13):
 
-Objects of type <protected/task_interface>'Class could be used as the
-prefix in a call on a synchronizing operation, and a run-time dispatch
-would occur to the "appropriate" entry/protected subprogram.
+    An entry_declaration in a task declaration {or an abstract_entry_declaration
+    in a task_interface_declaration} shall not contain a specification for
+    an access parameter (see 3.10).
 
-Question: Should we allow declaration of operations outside the
-protected/task_interface definition that take directly a
-a protected or task interface, as opposed to the corresponding class-wide type?
+Modify 9.5.2(20):
 
-Suggested answer: No, do not allow operations that directly take protected
-or task interfaces.  This means we avoid the whole issue of non-synchronizing
-dispatching operations for these types, which would require something
-analogous to tagged-type dispatching tables. By limiting ourselves to
-synchronizing operations, the implementation burden for supporting
-protected and task interfaces should be minimized.
+    An entry_declaration {or abstract_entry_declaration} with a ...
 
-!wording
+Modify 9.5.2(22/1):
 
-(See proposal.)
+    The elaboration of an entry_declaration {or abstract_entry_declaration} for
+    an entry family ... The elaboration of an entry_declaration {or
+    abstract_entry_declaration} for a single entry has no effect.
 
 !example
 
@@ -259,12 +395,11 @@
     Worker_Manager.Add_Queue_To_Be_Serviced(My_Queue'Access);
     ...
 
-
 !discussion
 
 During the Ada 95 design process, it was recognized that type extension
 might be useful for protected types (and possibly task types) as well as
-for record types.  However, at the time, both type extension and
+for record types. However, at the time, both type extension and
 protected types were somewhat controversial, and expending energy on a
 combination of these two controversial features was not practical.
 
@@ -286,11 +421,36 @@
 
 An important advantage of eliminating inheritance of any code or data
 for tasks and protected types is that the "monitor"-like benefits of
-these constructs are preserved.  All of the synchronizing operations are
+these constructs are preserved. All of the synchronizing operations are
 implemented in a single module, simplifying analysis and avoiding any
 inheritance "anomolies" that have been associated in the literature with
 combining inheritance with synchronization.
 
+As with "normal" interfaces, a "concrete" type that inherits from
+an interface must override all abstract operations, but may inherit
+null procedures. We have not proposed null entries, since it is unclear
+what would be the barriers for those (True or False) or how they would
+fit into a task body (no accept statement?).
+
+Objects of type <protected/task_interface>'Class can be used as the
+prefix in a call on a synchronizing operation, and a run-time dispatch
+would occur to the "appropriate" entry/protected subprogram.
+
+Question: Should we allow declaration of operations outside the
+protected/task_interface definition that take directly a
+a protected or task interface, as opposed to the corresponding class-wide type?
+
+Suggested answer: Initially we suggested no, but Pascal pointed out that
+our original proposal didn't really integrate inheritance between tagged types and
+task/protected types. However, we now allow "normal" limited interface types
+as ancestors of task and protected types or interfaces. This implies that
+we will have to support dispatching calls through lim-interface'class for
+such task and protected types, so we might as well allow task and protected
+interfaces to have primitive subprograms as well. Note that this capability
+is clearly separable from the "dispatching" inherent in invoking entries
+and protected subprograms, and could be dropped from the proposal if it
+is felt to overburden it.
+
 --!corrigendum 03.0x.0x(0x)
 
 !ACATS test
@@ -515,3 +675,409 @@
 
 ****************************************************************
 
+From: Tucker Taft
+Sent: Thursday, January 22, 2004  10:34 AM
+
+Here is the first write-up of this AI that includes
+"real" wording.  In response to Pascal's concern that
+we weren't *really* integrating inheritance between
+tagged and task/protected types, I have modified this
+proposal to allow task/protected types to be derived
+from "normal" limited interfaces as well as from
+task/protected interfaces.  I don't believe this imposes
+a significant added implementation burden, and clearly
+provides better integration of inheritance capabilities.
+However, it would be easy enough to "back out" this
+added capabiltiy, if it is felt to overburden the
+proposal.
+
+In my view it would also be nice to allow non-limited
+types to be derived from limited interfaces, but that
+depends on fixing the return-by-reference function
+morass, perhaps via the "aliased" return proposal.
+In any case, that idea is essentially unrelated to
+this AI, except in that it also provides further integration
+of inheritance capabilities.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, January 22, 2004  10:34 AM
+
+Here is the first write-up of this AI that includes
+"real" wording.  In response to Pascal's concern that
+we weren't *really* integrating inheritance between
+tagged and task/protected types, I have modified this
+proposal to allow task/protected types to be derived
+from "normal" limited interfaces as well as from
+task/protected interfaces.  I don't believe this imposes
+a significant added implementation burden, and clearly
+provides better integration of inheritance capabilities.
+However, it would be easy enough to "back out" this
+added capabiltiy, if it is felt to overburden the
+proposal.
+
+In my view it would also be nice to allow non-limited
+types to be derived from limited interfaces, but that
+depends on fixing the return-by-reference function
+morass, perhaps via the "aliased" return proposal.
+In any case, that idea is essentially unrelated to
+this AI, except in that it also provides further integration
+of inheritance capabilities.
+
+[Editor's note: this is version /03.]
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Thursday, January 22, 2004  11:35 AM
+
+Tucker Taft wrote:
+
+> Here is the first write-up of this AI that includes "real" wording...
+
+I like it.  I do have one nit to pick that is not a serious issue:
+
+>        Legality Rules
+>
+>    Only a tagged type shall have the reserved word abstract in its
+>    declaration.
+
+A (hostile) reading of this rule is that abstract can only appear in
+(tagged) TYPE declarations.  A clearer wording might be:
+
+"A type declaration that has the reserved word abstract in its
+definition shall be a tagged type."
+
+We could even go a little further and say: " ...a tagged view of a
+type."  That makes it clear that private views must include tagged or
+with, and a derived abstract type must be derived from a tagged view.
+
+I admit I am being pedantic, but I think that is the proper way to read
+proposed wording.
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Thursday, January 22, 2004  11:36 AM
+
+> "A type declaration that has the reserved word abstract in its
+> definition shall be a tagged type."
+
+Yes, that's better wording.  Or just, "...shall be tagged".
+
+> We could even go a little further and say: " ...a tagged view of a
+> type."  That makes it clear that private views must include tagged or
+> with, and a derived abstract type must be derived from a tagged view.
+
+I don't think we need to say "view".  The RM contains many places where
+"type" must be interpreted to mean "view of a type".
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, January 22, 2004  11:47 AM
+
+> Robert Eachus said:
+>
+> > "A type declaration that has the reserved word abstract in its
+> > definition shall be a tagged type."
+>
+> Yes, that's better wording.  Or just, "...shall be tagged".
+
+Well I think you need to say "shall be *for* a tagged type."
+A type declaration is not itself "tagged".
+
+In any case, I started from the admittedly somewhat awkward
+existing Ada 95 wording and tried to preserve the "spirit" of it:
+
+   Only a tagged type is allowed to be declared abstract.
+
+became:
+
+  Only a tagged type shall have the reserved word abstract
+  in its declaration.
+
+I don't love it, but I'm not sure I really prefer the above
+proposed alternatives either.  Any other opinions?
+
+> > We could even go a little further and say: " ...a tagged view of a
+> > type."  That makes it clear that private views must include tagged or
+> > with, and a derived abstract type must be derived from a tagged view.
+>
+> I don't think we need to say "view".  The RM contains many places where
+> "type" must be interpreted to mean "view of a type".
+
+I agree.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Thursday, January 22, 2004  4:01 PM
+
+>I don't think we need to say "view".  The RM contains many places where
+>"type" must be interpreted to mean "view of a type".
+
+I have no problem with that.  And my proposed new wording was really a
+fishing expedition to find a better way to say it.  One alternative is:
+
+a) "A type declaration that contains the reserved word abstract shall
+declare a tagged type."
+
+Of course, the temptation to replace "shall" by "must" must be resisted. ;-)
+
+b) A declaration of a non-tagged type is illegal if it contains the
+reserved word abstract."
+
+works and isn't too stilted.  Better might be:
+
+c) "A type declaration that contains the reserved word abstract is
+illegal if  it does not declare a tagged type."
+
+But althought the meaning is clear, it is technically nonsense.  An
+illegal declaration doesn't declare anything.  That brings us to:
+
+d) "A type declaration that contains the reserved word abstract is legal
+only if it declares a tagged type."
+
+Alternative d is shorter than c, and does a good job of making its
+intent clear.  Can we go further and say:
+
+e) "An abstract type declaration shall declare a tagged type."
+
+That opens a can of worms, but I think it is one that is worth opening.
+Right now, the proposal says that task interface types and protected
+interface types are also abstract types.  If we change the definitions
+around, we could have "abstract types", "task interface types", and
+"protected interface types" be exclusive.  I could go through and make
+the other changes if people think it is worth it.  As I see it, doing
+that would clean up a lot of awkward text, expecially in  the proposed
+3.9.4(1), and in the changes to 9.1 and 9.4.
+
+Abstract type does not seem to currently be heavily used in the RM, and
+in any case we would now not be changing the meaning of the technical
+term.  What does get used is abstract subprogram.  Adding abstract
+entries means that we should add that a call to an abstract entry must
+be dispatching.  (Excuse me, shall be dispatching.)
+
+Tucker said: "In my view it would also be nice to allow non-limited
+types to be derived from limited interfaces, but that depends on fixing
+the return-by-reference function  morass, perhaps via the "aliased"
+return proposal.
+In any case, that idea is essentially unrelated to this AI, except in
+that it also provides further integration
+of inheritance capabilities."
+
+If we do adopt the final alternative above, it might make it harder to
+do this.  But I don't see any benefit to allowing non-tasks to inherit
+from  task interfaces or non-protected types to inherit from protected
+interfaces  (I also can't imagine syntax rules that would allow anything
+new other than protected types inheriting from a task interface, or vice
+versa.)  So it does seem to be unrelated.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, January 22, 2004   4:28 PM
+
+> Alternative d is shorter than c, and does a good job of making its
+> intent clear.  Can we go further and say:
+>
+> e) "An abstract type declaration shall declare a tagged type."
+
+Now you are pretty much back to where I started with Ada 95.
+The whole point was to allow abstract types to include
+interfaces.  I think this is a bug in the current wording of
+AI-251, by the way.
+
+> That opens a can of worms, but I think it is one that is worth opening.
+> Right now, the proposal says that task interface types and protected
+> interface types are also abstract types.  If we change the definitions
+> around, we could have "abstract types", "task interface types", and
+> "protected interface types" be exclusive.
+
+Why would that be a good idea?  An abstract type is one that
+is not allowed to have objects (aka "instances" in OO parlance).
+
+> ... I could go through and make
+> the other changes if people think it is worth it.  As I see it, doing
+> that would clean up a lot of awkward text, expecially in  the proposed
+> 3.9.4(1), and in the changes to 9.1 and 9.4.
+
+I don't agree at all.  We didn't invent the notion
+of "abstract type."  It is well established in the OO
+literature as a type that should not have any instances.
+That applies to all interface types, as well as all
+types explicitly declared "abstract."
+
+> Abstract type does not seem to currently be heavily used in the RM, and
+> in any case we would now not be changing the meaning of the technical
+> term.
+
+We would be changing the fundamental meaning of "abstract" type.
+
+> ... What does get used is abstract subprogram.  Adding abstract
+> entries means that we should add that a call to an abstract entry must
+> be dispatching.  (Excuse me, shall be dispatching.)..
+
+I'm not sure that is necessary.  Entry queues are
+associated with objects, and calls are added to entry
+queues and then "serviced".  I think that provides
+the implicit level of indirection that is equivalent
+to dispatching.  On the other hand, we may need
+to say something more about protected subprogram calls
+when the prefix is class-wide.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, January 22, 2004  12:02 PM
+
+Tucker Taft wrote:
+
+> ... I have modified this
+> proposal to allow task/protected types to be derived
+> from "normal" limited interfaces as well as from
+> task/protected interfaces.  ...
+
+I suppose we could take one further step, and allow
+task types/interfaces to be derived from protected
+interfaces that have only abstract entry/entry families.
+
+Going the other way (deriving protected types/interfaces
+from task types) doesn't seem wise, because there
+are various operations you can apply to task_int'class
+which wouldn't make sense for protected objects
+(e.g. abort, 'identity).
+
+On the other hand, I don't know of any operations
+that can be applied to a protected object with only
+entries that couldn't also be applied to a task.
+
+Again, this is incremental functionality that is
+not essential to the basic proposal, and shouldn't
+be allowed to overburden it...
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, January 22, 2004   7:16 PM
+
+Tucker Taft wrote:
+>
+> > ... I have modified this
+> > proposal to allow task/protected types to be derived
+> > from "normal" limited interfaces as well as from
+> > task/protected interfaces.  ...
+>
+> I suppose we could take one further step, and allow
+> task types/interfaces to be derived from protected
+> interfaces that have only abstract entry/entry families.
+
+I don't know if that is useful. But the problem with this proposal is that
+it doesn't seem to help in all of the cases where you might want to mix
+implementations.
+
+For one thing, while a task can be derived from a "regular" limited
+interface, such an interface has to be devoid of operations -- making the
+capability fairly useless.
+
+For another thing, a lot of the capabilities that you might want don't seem
+to be possible.
+
+Consider a queue interface (I'm using fixed items here for simplicity; it's
+likely that this whole thing would be wrapped in a generic):
+
+  package AQ is
+    type Abstract_Queue is limited interface;
+    procedure Add_Item (Queue : in out Abstract_Queue; Item : in Integer);
+    procedure Remove_Item (Queue : in out Abstract_Queue; Item : out Integer);
+  end AQ;
+
+Then the standard implementation would look something like:
+   with AQ;
+   package NQ is
+      type Queue is new AQ.Abstract_Queue with private;
+      procedure Add_Item (Queue : in out Queue; Item : in Integer);
+      procedure Remove_Item (Queue : in out Queue; Item : out Integer);
+         -- Raises Empty_Error if empty.
+      Empty_Error : exception;
+   end NQ;
+
+Of course, the interface could be used in other components that needed a
+queue.
+
+Now, say you want a version of a queue to use for multiple tasks, which
+blocks on empty rather than raising an exception. You'd write something
+like:
+
+   with AQ;
+   package PQ is
+      protected type Blocking_Queue is new AQ.Abstract_Queue with
+         procedure Add_Item (Item : in Integer);
+         entry Remove_Item (Item : out Integer);
+      private ...
+      end Blocking_Queue;
+   end PQ;
+
+But of course that isn't allowed, because Remove_Item isn't a procedure.
+Moreover, these aren't subtype conformant. Your wording fails to take into
+account the implied object of the calls.
+(Also, Remove_Item can't be a function, because of some stupid rule about
+"in out" parameters on functions. I've made it a procedure here for that
+reason - Ada functions are useless for O-O programming other than possibly
+constructors. But's that's another argument. Note that the usual
+work-arounds aren't going to work for a protected type, because you can't
+change the implied parameter's mode or handling.)
+
+   with AQ;
+   package PQ1 is
+      protected type Blocking_Queue is new AQ.Abstract_Queue with
+         procedure Add_Item (Item : in Integer);
+         procedure Remove_Item (Item : out Integer);
+         entry Blocking_Remove_Item (Item : out Integer);
+      private ...
+      end Blocking_Queue;
+   end PQ1;
+
+Doesn't work either, because Remove_Item can't call Blocking_Remove_Item
+(can't call blocking operations in a protected object). A Remove_Item that
+raised an exception would work, but it would defeat the purpose of having
+the operation.
+
+So, you'd have to resort to a wrapper type (assuming the protected type in
+PQ above exists):
+
+   with AQ, PQ;
+   package PQ2 is
+      type Blocking_Queue is new AQ.Abstract_Queue with record
+         Real_Queue : PQ.Blocking_Queue;
+      end record;
+      procedure Add_Item (Queue : in out Blocking_Queue; Item : in Integer);
+      procedure Remove_Item (Queue : in out Blocking_Queue; Item : out Integer);
+   end PQ2;
+
+Now you can use your protected queue object in the other components. But
+now, it is no longer protected, unless you make the component itself visible
+(as I did above). So callers that want to use (say) a timed entry call would
+have to call the component of the queue, not an operation on the queue.
+That's pretty ugly.
+
+Moreover, if you're willing to write wrappers, you don't need the ability to
+use "regular" interfaces on protected types in the first place. Just write
+the wrapper and be done with it. The beauty of this idea is to get the
+compiler to write any needed wrappers. (Or generate its code so it doesn't
+need any.)
+
+Thus, I think that an entry should be able to "match" a procedure with the
+proper parameter list (and no family). (This would essentially be the prefix
+call mechanism in reverse.) The call would operate like a procedure call. We
+already allow this in Ada, as an entry can be renamed as a procedure.
+Allowing that would make the above example easy, and also would make a
+"regular" interface useful for a task.
+
+Without it, I don't see much point in the whole mechanism. Other than basic
+locks (which you should avoid anyway), there don't seem to be that many
+cases of wanting multiple implementations of protected objects or tasks.
+
+****************************************************************

Questions? Ask the ACAA Technical Agent