CVS difference for ais/ai-00345.txt

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

--- ais/ai-00345.txt	2004/10/05 22:49:16	1.14
+++ ais/ai-00345.txt	2004/11/14 06:37:15	1.15
@@ -1,4 +1,4 @@
-!standard  3.09.01    (03)                             04-07-02  AI95-00345/06
+!standard  3.09.01    (03)                             04-11-11  AI95-00345/07
 !standard  2.09       (02)
 !standard  3.09.03    (01)
 !standard  3.09.03    (02)
@@ -40,15 +40,6 @@
 override the primitive of the interface once it has been transformed
 into a "prefix" notation a la AI-252.
 
-Rather than declaring an interface "limited," an interface
-may be specified as a "task," "protected," or "synchronized" interface.
-In this case, the interface can only be implemented by, respectively,
-a task type, a protected type, or either a task or protected type.
-
-A class-wide object of an interface type that implements a task
-interface type is a task object, allowing operations such as
-abort, 'Identity, 'Callable, etc. to be applied to it.
-
 !problem
 
 The object-oriented features of Ada 95 are essentially disjoint with
@@ -59,9 +50,206 @@
 access to the object designated by the access discriminant.
 
 !proposal
+
+AI-251 introduces interfaces which may be composed to form further
+interfaces. Tagged types can be derived from one or more interfaces
+(plus possibly one other tagged type). Furthermore, interfaces may be
+limited.
+
+The proposal here is to introduce further categories of interface,
+namely synchronized, protected, and task interfaces. A synchronized
+interface can be implemented by either a task or protected type; a
+protected interface can only be implemented by a protected type and a
+task interface can only be implemented by a task type.
+
+Moreover, an explicitly marked limited interface can be implemented by
+a "normal" limited tagged type or by a protected or task type. Remember
+that task and protected types are inherently limited. Note that we use
+the term limited interface to refer collectively to interfaces marked
+limited, synchronized, task or protected and we use explicitly limited
+to refer to those actually marked as limited.
+
+So we can write
+
+   type LI is limited interface;  -- similarly type LI2
+
+   type TI is task interface;
+
+   type PI is protected interface;
+
+   type SI is synchronized interface;
+
+and we can of course provide operations which must be abstract or null.
+(Note that synchronized is a new reserved word.)
+
+We can compose these interfaces provided that no conflict arises. The
+following are all permitted:
+
+   type TI3 is task interface and LI and TI;
+
+   type LI3 is limited interface and LI and LI2;
+
+   type TI4 is task interface and LI and LI2;
+
+   type SI3 is synchronized interface and LI and LI2 and SI
+
+The rule is simply that we can compose two or more interfaces provided
+that we do not mix task and protected interfaces and the resulting
+interface must be not earlier in the hierarchy, limited, synchronized,
+task/protected than any of the ancestor interfaces.
 
-(See wording.)
+We can derive a real task type or protected type from one or more of the
+appropriate interfaces
 
+   task type TT is new TI with
+       -- and here we give entries as usual
+   end TT;
+
+or
+
+   protected type PT is new LI and SI with
+   ...
+   end PT;
+
+Unlike tagged record types we cannot derive a task or protected type
+from another task or protected type as well. So the derivation hierarchy
+can only be one level deep once we declare actual task or protected
+types.
+
+The operations of these various interfaces are declared in the usual way
+and an interface composed of several interfaces has the operations of
+all of them with the same rules regarding duplication and overriding of
+an abstract operation by a null one and so on as for explicitly tagged
+types.
+
+When we declare an actual task or protected type then we must implement
+all of the operations of the interfaces concerned. This can be done in
+two ways, either by declaring an entry or protected operation in the
+specification of the task or protected object or by declaring a distinct
+subprogram in the same list of declarations (but not both). Of course,
+if an operation is null then it can be inherited or overridden as usual.
+
+Thus the interface
+
+   package Pkg is
+      type TI is task interface;
+      procedure P(X: in TI) is abstract;
+      procedure Q(X: in TI; I: in Integer) is null;
+   end Pkg;
+
+could be implemented by
+
+   package PT1 is
+      task type TT1 is new TI with      -- P and Q implemented by entries
+         entry P;
+         entry Q(I: in Integer);
+      end TT1;
+   end PT1;
+
+or by
+
+   package PT2 is
+      task type TT2 is new TI with      -- P implemented by an entry
+         entry P;                       -- Q implemented by a procedure
+      end TT2;
+      procedure Q(X: in TT2; I: in Integer);
+   end PT2;
+
+or even by
+
+   package PT3 is
+      task type TT3 is new TI with end; -- P implemented by a procedure
+                                        -- Q inherited as a null procedure
+      procedure P(X: in TT3; I: in Integer);
+   end PT3;
+
+Note how the first parameter which denotes the task is omitted if it
+is implemented by an entry. This echoes the new Obj.Op notation for
+tagged types in general.
+
+In order for the implementation of an operation by an entry of a task
+type or a protected operation of a protected type to be possible some
+fairly obvious conditions must be satisfied.
+
+In all cases the first parameter of the operation must be of the task
+type or protected type (it may be an access parameter).
+
+In addition, in the case of a protected type, the first parameter of
+an operation implemented by a protected procedure or entry must have
+mode in or in out (and in the case of an access parameter it must be
+an access to variable parameter).
+
+If the operation does not fit these rules then it has to be implemented
+as a subprogram. An important example is that a function has to be
+implemented as a function in the case of a task type because there is
+no such thing as a function entry.
+
+Entries and protected operations which implement inherited operations
+may be in the visible part or private part of the task or protected type
+in the same way as for tagged record types.
+
+Of course a task or protected type which implements an interface can
+have additional entries and operations as well just as a derived tagged
+type can have more operations than its parent.
+
+Having declared a number of types implementing a interface then we
+can dispatch to the various operations in the usual way. Thus an
+interface might be implemented by a limited tagged type (plus its
+various operations) and by a protected type and also by a task type.
+We could then dispatch to the operations of any of these according to
+the tag of the type concerned. Observe that task and protected types
+are now other forms of tagged types and so we have to be careful to
+say tagged record type where appropriate.
+
+Furthermore, because a dispatching call might be to an entry or to a
+procedure we now permit what appear to be procedure calls in selective
+entry calls which might dispatch to an entry. We also permit calls on
+entries renamed as procedures and formal subprograms since these might
+also be implemented as entries.
+
+The important point to note of course is that we can as usual assume the
+common properties of the class concerned. Thus in the case of a task
+interface we know that it must be implemented by a task and so the
+operations such as abort and the attributes Identity, Callable and so on
+can be applied. If we know that an interface is synchronized then we do
+know that it has to be implemented by a task or a protected type and
+so is thread-safe.
+
+We always explicitly insert limited, synchronized, task or, protected
+in the case of a limited interface in order to avoid confusion. So if
+we derive a new explicitly limited interface from an exising one then we
+have to write
+
+   type LI2 is limited interface and LI;
+
+whereas in the case of normal types we write
+
+    type LT is limited....
+    type NLT is new LT with ...                -- T is limited
+
+then NLT is limited by the normal derivation rules. Remember by contrast
+that types take their limitedness from their parent (the first one in the
+list) and it is not given explicitly on type derivation.
+
+Finally, note a rule regarding nonlimited and limited interfaces. All
+descendants of a nonlimited interface have to be nonlimited because
+otherwise limited types could end up with an assignment operation.
+
+This means that we cannot write
+
+   type NI is interface;                  -- nonlimited
+   type LI is limited interface;
+   task type T is new NI and LI with ...  -- illegal
+
+This is illegal because the interface NI in the declaration of T is
+not limited.
+
+However, a nonlimited interface or type can be a descendant of a limited
+interface. So the following are all permitted
+
+   type NI2 is interface and NI and LI;  -- NI2 is nonlimited
+   type NT is new T and LI with ...      -- T and NT are nonlimited
+
 !wording
 
 NOTE: This presumes AI-251 ("normal" interface types) and AI-252
@@ -163,82 +351,96 @@
     TASK TYPE defining_identifier [known_discriminant_part] [IS
       [NEW interface_list WITH]
       task_definition];
+
+Add after 9.1(9.1/1):
+
+    If a task_type_declaration includes an interface_list, the task type
+    is derived from each interface named in the interface_list.
+
+    For a task_type_declaration, if the first parameter of a primitive
+    inherited subprogram is of the task type or an access parameter designating
+    the task type, and there is an entry_declaration for a single entry with
+    the same identifier within the task_type_declaration, having a profile that
+    is type conformant with that of the inherited subprogram after omitting
+    this first parameter, the inherited subprogram is said to be
+    *implemented* by the conforming task entry.
+
+    AARM Note: The inherited subprograms can only come from an interface;
+    a task_type_declaration inherits no subprograms of its own.
 
-Add after 9.1(8):
+Move 9.1(8) and its heading after 9.1(9.1/1). Add the following after it:
 
     Each interface_subtype_mark of an interface_list appearing within a
     task_type_declaration shall denote a limited interface type that
     is not a protected interface.
 
-    If a task_type_declaration includes an interface_list, then for each
-    primitive subprogram inherited by the task type, at most one of the
-    following shall apply:
+    For each primitive subprogram inherited by the type declared by a
+    task_type_declaration, at most one of the following shall apply:
 
       - the inherited subprogram shall be overridden with a primitive
         subprogram of the task type, in which case the overriding
         subprogram shall be subtype conformant with the inherited
         subprogram and not abstract; or
 
-      - the first parameter of the inherited subprogram shall be of the
-        task type or an access parameter designating the task type, and there
-        shall be an entry_declaration for a single entry with the same
-        identifier and a profile that is type conformant with that of the
-        inherited subprogram after omitting this first parameter, in which case
-        the inherited subprogram is said to be "implemented" by the conforming
-        entry, and its profile after omitting the first parameter shall be
-        subtype conformant with that of the entry.
+      - the inherited subprogram is implemented by a single entry of the
+        task type, in which case its profile after omitting the first
+        parameter shall be subtype conformant with that of the task
+        entry.
 
     If neither applies, the inherited subprogram shall be a null procedure.
 
-Add after 9.1(9.1/1):
-
-    If a task_type_declaration includes an interface_list, the task type
-    is derived from each interface named in the interface_list.
-
 Change 9.4(2) to:
 
   protected_type_declaration ::=
     PROTECTED TYPE defining_identifier [known_discriminant_part] IS
       [NEW interface_list WITH]
       protected_definition;
+
+Add the following at end of 9.4(11), then add the new paragraphs:
+
+    If a protected_type_declaration includes an interface_list, the
+    protected type is derived from each interface named in the
+    interface_list.
+
+    For a protected_type_declaration, the first parameter of a primitive
+    inherited subprogram is of the protected type or an access parameter
+    designating the protected type, and there is a
+    protected_operation_declaration for a protected subprogram
+    or single entry with the same identifier within the
+    protected_type_declaration, having a profile that is type conformant with
+    that of the inherited subprogram after omitting this first parameter, the
+    inherited subprogram is said to be *implemented* by the conforming
+    protected subprogram or entry.
+
+    AARM Note: The inherited subprograms can only come from an interface;
+    a protected_type_declaration inherits no subprograms of its own.
 
-Add after 9.4(10):
+Move 9.4(10) and its heading after 9.4(11). Add the following after it:
 
     Each interface_subtype_mark of an interface_list appearing within a
     protected_type_declaration shall denote a limited interface type that
     is not a task interface.
 
-    If a protected_type_declaration includes an interface_list, then
-    for each primitive subprogram inherited by the protected type, at most
-    one of the following shall apply:
+    For each primitive subprogram inherited by the type declared by a
+    protected_type_declaration, at most one of the following shall apply:
 
-      - the inherited subprogram shall be overridden with a primitive
-        subprogram of the protected type; in this case the overriding
+      - the inherited subprogram is overridden with a primitive
+        subprogram of the protected type, in which case the overriding
         subprogram shall be subtype conformant with the inherited
         subprogram and not abstract; or
-
-      - the first parameter of the inherited subprogram shall be of the
-        protected type or an access parameter designating the protected type,
-        and there shall be a protected_operation_declaration for a protected
-        subprogram or single entry with the same identifier within the
-        protected_type_declaration, having a profile that is type conformant with
-        that of the inherited subprogram after omitting this first parameter;
-        in this case the inherited subprogram is said to be *implemented* by
-        the conforming protected subprogram or entry, and its profile after
-        omitting the first parameter shall be subtype conformant with that of
-        the protected subprogram or entry.
 
-    If neither applies, the inherited subprogram shall be a null procedure.
+      - the inherited subprogram is implemented by a protected
+        subprogram or single entry of the protected type,
+        in which case its profile after omitting the first parameter
+        shall be subtype conformant with that of the protected
+        subprogram or entry.
 
-    If an inherited subprogram is implemented by a protected procedure or
-    entry, then its first parameter shall be an access-to-variable parameter,
-    or of mode OUT or IN OUT.
+If neither applies, the inherited subprogram shall be a null procedure.
 
-Modify 9.4(11):
+If an inherited subprogram is implemented by a protected procedure or
+an entry, then the first parameter of the inherited subprogram shall be
+of mode OUT or IN OUT, or an access-to-variable parameter.
 
-    If a protected_type_declaration includes an interface_list, the
-    protected type is derived from each interface named in the
-    interface_list.
 
 Add at end of 9.7.2(1):
 
@@ -294,7 +496,7 @@
 Modify 9.7.4(6):
 
     For the execution of an asynchronous_select whose triggering_statement is
-    an [entry_call_statement] {procedure_or_entry_call}, the entry_name{,
+    [an entry_call_statement] {a procedure_or_entry_call}, the entry_name{,
     procedure_name, or procedure_prefix,} and actual parameters are evaluated
     as for a simple entry call (see 9.5.3) {or procedure call (see 6.4).}[,
     and] {If the call is an entry call or a call on a procedure implemented by
@@ -390,7 +592,7 @@
     use Queues;
 
     protected type Bounded_Queue(Max: Natural) is new Queues.Queue with
-      -- Implementation of a bounded, protectected queue
+      -- Implementation of a bounded, protected queue
         entry Enqueue(Elem : in Element_Type);
         entry Dequeue(Elem : out Element_Type);
         function Length return Natural;
@@ -514,7 +716,7 @@
 for tasks and protected types is that the "monitor"-like benefits of
 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
+inheritance "anomalies" that have been associated in the literature with
 combining inheritance with synchronization.
 
 After further investigation of interfaces specific to task and protected
@@ -556,12 +758,12 @@
 a "task" interface or a "protected" interface. To require that
 it be implemented by either a task or a protected type (to provide
 properly synchronized access to the data), the syntax allows an
-interface to be specifed as a "synchronized" interface.
+interface to be specified as a "synchronized" interface.
 Such interfaces cannot be implemented explicitly by
 "normal" tagged types.
 
 While we're relaxing restrictions, we've also eliminated the restriction
-that prevented a limited interface from being implemented by a non-limited
+that prevented a limited interface from being implemented by a nonlimited
 type. This restriction existed primarily because of difficulties determining
 the difference between normal and return-by-reference types. Since AI-318-2
 has relegated return-by-reference types to the dustbin of history, there no
@@ -570,8 +772,16 @@
 limited or non-limited), a task type, or a protected type.
 
 This proposal also makes a slight change to the syntax of interfaces, adding
-the reserved word AND in order to make the definition interfaces more readable.
+the reserved word AND in order to make the definition of interfaces more
+readable.
 
+Note finally that we permit overriding in the private part. One value of
+this with protected types is that this allows an interface to be implemented
+without making visible whether a particular procedure of the interface is
+implemented by an entry or by a protected procedure. This provides the
+freedom to change the details regarding synchronization at a later date if
+necessary.
+
 IMPLEMENTATION NOTES:
 
 Given a select statement like:
@@ -613,7 +823,7 @@
 prefix notation), it could instead be translated
 (roughly) into:
 
-    Sync_Obj : Limited_Interface'Class
+    Sync_Obj : Limited_Interface'Class;
    ...
     type Call_Status is (Not_An_Entry, Completed, Not_Completed);
     Status : Call_Status := Not_An_Entry;
@@ -760,7 +970,7 @@
 Two @fa<discrete_subtype_definition>s are @i<fully conformant> if they are
 both @fa<subtype_indication>s or are both @fa<range>s, the @fa<subtype_mark>s
 (if any) denote the same subtype, and the corresponding @fa<simple_expression>s
-of the ranges (if any) fully conform.
+of the @fa<range>s (if any) fully conform.
 @dinst
 Two subprograms or entries are @i<type conformant> (respectively @i<mode
 conformant>, @i<subtype conformant>, or @i<fully conformant>) if their profiles
@@ -780,43 +990,52 @@
 
 !corrigendum 9.1(8)
 
-@dinsa
+@ddel
+@i<@s8<Legality Rules>>
+
 A task declaration requires a completion, which shall be a @fa<task_body>, and
 every @fa<task_body> shall be the completion of some task declaration.
+
+!corrigendum 9.1(9.1/1)
+
+@dinsa
+For a task declaration without a @fa<task_definition>, a @fa<task_definition>
+without @fa<task_item>s is assumed.
 @dinss
+If a @fa<task_type_declaration> includes an @fa<interface_list>, the task type
+is derived from each interface named in the @fa<interface_list>.
+
+For a @fa<task_type_declaration>, if the first parameter of a primitive
+inherited subprogram is of the task type or an access parameter designating he
+task type, and there is an @fa<entry_declaration> for a single entry with the
+same identifier within the @fa<task_type_declaration>, having a profile that is
+type conformant with that of the inherited subprogram after omitting this first
+parameter, the inherited subprogram is said to be @i<implemented> by the
+conforming task entry.
+
+@i<@s8<Legality Rules>>
+
+A task declaration requires a completion, which shall be a @fa<task_body>, and
+every @fa<task_body> shall be the completion of some task declaration.
+
 Each @fa<interface_subtype_mark> of an @fa<interface_list> appearing within a
 @fa<task_type_declaration> shall denote a limited interface type that
 is not a protected interface.
 
-If a @fa<task_type_declaration> includes an @fa<interface_list>, then for each
-primitive subprogram inherited by the task type, at most one of the
-following shall apply:
+For each primitive subprogram inherited by the type declared by a
+@fa<task_type_declaration>, at most one of the following shall apply:
 
 @xbullet<the inherited subprogram shall be overridden with a primitive
 subprogram of the task type, in which case the overriding
 subprogram shall be subtype conformant with the inherited
 subprogram and not abstract; or>
 
-@xbullet<the first parameter of the inherited subprogram shall be of the
-task type or an access parameter designating the task type, and there
-shall be an @fa<entry_declaration> for a single entry with the same
-identifier and a profile that is type conformant with that of the
-inherited subprogram after omitting this first parameter, in which case
-the inherited subprogram is said to be @i<implemented> by the conforming
-entry, and its profile after omitting the first parameter shall be
-subtype conformant with that of the entry.>
+@xbullet<the inherited subprogram is implemented by a single entry of the
+task type; in which case its profile after omitting the first
+parameter shall be subtype conformant with that of the task entry.>
 
 If neither applies, the inherited subprogram shall be a null procedure.
 
-!corrigendum 9.1(9.1/1)
-
-@dinsa
-For a task declaration without a @fa<task_definition>, a @fa<task_definition>
-without @fa<task_item>s is assumed.
-@dinst
-If a @fa<task_type_declaration> includes an @fa<interface_list>, the task type
-is derived from each interface named in the @fa<interface_list>.
-
 !corrigendum 9.4(2)
 
 @drepl
@@ -830,39 +1049,12 @@
 
 !corrigendum 9.4(10)
 
-@dinsa
+@ddel
+@i<@s8<Legality Rules>>
+
 A protected declaration requires a completion, which shall be a
 @fa<protected_body>, and every @fa<protected_body> shall be the completion of
 some protected declaration.
-@dinss
-Each @fa<interface_subtype_mark> of an @fa<interface_list> appearing within a
-@fa<protected_type_declaration> shall denote a limited interface type that
-is not a task interface.
-
-If a @fa<protected_type_declaration> includes an @fa<interface_list>, then
-for each primitive subprogram inherited by the protected type, at most
-one of the following shall apply:
-
-@xbullet<the inherited subprogram shall be overridden with a primitive
-subprogram of the protected type; in this case the overriding subprogram shall
-be subtype conformant with the inherited subprogram and not abstract; or>
-
-@xbullet<the first parameter of the inherited subprogram shall be of the
-protected type or an access parameter designating the protected type, and there
-shall be a @fa<protected_operation_declaration> for a protected subprogram or
-single entry with the same identifier within the
-@fa<protected_type_declaration>, having a profile that is type conformant with
-that of the inherited subprogram after omitting this first parameter; in this
-case the inherited subprogram is said to be @i<implemented> by the conforming
-protected subprogram or entry, and its profile after omitting the first
-parameter shall be subtype conformant with that of the protected
-subprogram or entry.>
-
-If neither applies, the inherited subprogram shall be a null procedure.
-
-If an inherited subprogram is implemented by a protected procedure or
-entry, then its first parameter shall be an access-to-variable parameter,
-or of mode @b<out> or @b<in out>.
 
 !corrigendum 9.4(11)
 
@@ -883,6 +1075,46 @@
 @fa<protected_type_declaration> includes an @fa<interface_list>, the
 protected type is derived from each interface named in the @fa<interface_list>.
 
+For a @fa<protected_type_declaration>, the first parameter of a primitive
+inherited subprogram is of the protected type or an access parameter
+designating the protected type, and there is a
+@fa<protected_operation_declaration> for a protected subprogram
+or single entry with the same identifier within the
+@fa<protected_type_declaration>, having a profile that is type conformant with
+that of the inherited subprogram after omitting this first parameter, the
+inherited subprogram is said to be @i<implemented> by the conforming
+protected subprogram or entry.
+
+@i<@s8<Legality Rules>>
+
+A protected declaration requires a completion, which shall be a
+@fa<protected_body>, and every @fa<protected_body> shall be the completion of
+some protected declaration.
+
+Each @fa<interface_subtype_mark> of an @fa<interface_list> appearing within a
+@fa<protected_type_declaration> shall denote a limited interface type that
+is not a task interface.
+
+For each primitive subprogram inherited by the type declared by a
+@fa<protected_type_declaration>, at most one of the following shall apply:
+
+@xbullet<the inherited subprogram is overridden with a primitive
+subprogram of the protected type, in which case the overriding
+subprogram shall be subtype conformant with the inherited
+subprogram and not abstract; or>
+
+@xbullet<the inherited subprogram is implemented by a protected
+subprogram or single entry of the protected type,
+in which case its profile after omitting the first parameter
+shall be subtype conformant with that of the protected
+subprogram or entry.>
+
+If neither applies, the inherited subprogram is a null procedure.
+
+If an inherited subprogram is implemented by a protected procedure or
+an entry, then the first parameter of the inherited subprogram shall be
+of mode @b<out> or @b<in out>, or an access-to-variable parameter.
+
 !corrigendum 9.7.2(1)
 
 @drepl
@@ -902,7 +1134,7 @@
    entry_call_statement [sequence_of_statements]>>
 @dby
 @xcode<@fa<entry_call_alternative ::=
-   procedure_or_entry_call_statement [sequence_of_statements]>>
+   procedure_or_entry_call [sequence_of_statements]>>
 
 @xcode<@fa<procedure_or_entry_call ::=
    procedure_call_statement | entry_call_statement>>
@@ -939,16 +1171,16 @@
 evaluating the @i<delay_>@fa<expression> of the @fa<delay_alternative>. If the
 call is an entry call or a call on a procedure implemented by an entry, the
 entry call is then issued. Otherwise, the call proceeds as described in 6.4 for
-a procedure call, followed by the sequence_of_statements of the
-entry_call_alternative, and the delay_alternative sequence_of_statements is
-ignored.
+a procedure call, followed by the @fa<sequence_of_statements> of the
+@fa<entry_call_alternative>, and the @fa<delay_alternative>
+@fa<sequence_of_statements> is ignored.
 
 !corrigendum 9.7.4(4)
 
 @drepl
 @xcode<@fa<triggering_statement ::= entry_call_statement | delay_statement>>
 @dby
-@xcode<@fa<triggering_statement ::= procedure_or_entry_call_statement | delay_statement>>
+@xcode<@fa<triggering_statement ::= procedure_or_entry_call | delay_statement>>
 
 !corrigendum 9.7.4(6)
 
@@ -961,9 +1193,9 @@
 and never requeued-with-abort, then the @fa<abortable_part> is never started.
 @dby
 For the execution of an @fa<asynchronous_select> whose
-@fa<triggering_statement> is an @fa<procedure_or_entry_call_statement>, the
-@i<entry_>@fa<name>, @i<procedure_>@fa<name>, or @i<procedure_>@fa<prefix>, and
-any actual parameters are evaluated as for a simple entry
+@fa<triggering_statement> is a @fa<procedure_or_entry_call>, the
+@i<entry_>@fa<name>, @i<procedure_>@fa<name>, or @i<procedure_>@fa<prefix>,
+and actual parameters are evaluated as for a simple entry
 call (see 9.5.3) or procedure call (see 6.4). If the call is an entry call or a
 call on a procedure implemented by an entry, the entry call is issued. If the
 entry call is queued (or requeued-with-abort), then the @fa<abortable_part> is
@@ -1034,6 +1266,8 @@
 
 !ACATS test
 
+Created ACATS tests (both B and C tests) for this feature.
+
 !appendix
 
 From: Randy Brukardt
@@ -4191,6 +4425,849 @@
 Sent: Monday, April 5, 2004  10:41 AM
 
 Makes sense.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 26, 2004  7:33 AM
+
+John and Pascal have noticed a hole in the wording for
+AI-345 where we don't clearly indicate the intent that
+a nonlimited type may implement a limited interface.
+This leads to the question of what determines whether
+a derived type declared with one or more limited interface
+ancestors is limited or nonlimited.  The simplest rule
+is that a derived type is nonlimited if at least one
+of its ancestors is nonlimited.  However, what if
+you want to have a nonlimited type all of whose
+interface ancestors are limited?
+
+In thinking about this last night, I had a couple of
+ideas.  Presuming we like having limited interfaces
+implemented by nonlimited types, then we need
+a way to declare a nonlimited type all of whose
+interface ancestors are limited.  I realized that the simplest
+solution would be to have a ready-made nonlimited
+interface sitting around and just throw that in as
+another interface ancestor.  E.g.:
+
+    type My_Nonlimited_Type is new Lim_Int1 and Lim_Int2
+      and Nonlimited_Interface with private;
+
+where Nonlimited_Interface is declared:
+
+    type Nonlimited_Interface is interface;
+
+with *no* primitive operations.
+
+This got me to thinking about the possibility of whether
+we could imagine that *all* nonlimited tagged types had
+such an interface as their ancestor.  This would allow you
+to create "very" polymorphic lists using
+Nonlimited_Interface'class as the element type.
+
+This naturally led me to thinking about an even more polymorphic
+list, presuming we had a limited interface which every
+tagged type, whether limited or non-limited, was considered
+a descendant.  The same could go for synchronized, protected,
+and task.  This led me to something like:
+
+     package Ada.Roots is
+        type Limited_Root is limited interface;
+        type Nonlimited_Root is interface and Limited_Root;
+        type Synchronized_Root is synchronized interface and Limited_Root;
+        type Task_Root is task interface and Synchronized_Root;
+        type Protected_Root is protected interface and Synchronized_Root;
+     end Ada.Roots;
+
+I suppose all of these names could be inverted, producing
+"Root_Limited," "Root_Nonlimited", etc., but since "limited,"
+"synchronized", and "protected" are clearly adjectives, I
+somewhat preferred the above order.
+
+In any case, the important point is that *all* tagged types
+would be considered to be covered by Limited_Root'Class,
+all nonlimited tagged types would be covered by Nonlimited_Root'Class,
+all protected types would be covered by Protected_Root'Class,
+and all task types would be covered by Task_Root'Class.
+
+In addition to "solving" the problem with a nonlimited
+type with only limited interface ancestors, having these
+root interfaces could be quite useful.  Most O-O languages
+have a root type, often called "Object."  This can be
+quite useful, and perhaps adding something like this should
+be considered part of the Ada 2005 "rounding out" of the
+O-O model.  Note that allowing extensions at a nested scope
+helps make this possible.
+
+Having these might also simplify the creation of something like
+the "generic constructor" we have proposed.
+
+By the way, on the technical point of how to decide whether
+a derived type is limited or nonlimited, an alternative
+approach is to determine it based on the *first* (primary)
+parent, and then consider it an error if a limited type
+has a nonlimited ancestor.  That might be friendlier to
+the reader -- you would only have to look at the first
+parent to determine the properties of the derived type.
+So the above example would become:
+
+     type My_Nonlimited_Type is new Ada.Roots.Nonlimited_Root and
+        Lim_Int1 and Lim_Int2 with private;
+
+A second point -- if we add these "root" types I would simplify
+the rules for task and protected types and make them *all*
+treated as "synchronized tagged" types, independent of whether they
+have an explicit interface as an ancestor.  Currently, only if
+a task or protected type has an interface ancestor can you use the
+'Tag attribute with it.  The thought was that perhaps this would
+provide a smoother transition from Ada 95, but having a "Task_Root"
+interface seems so useful, that whatever marginal value there is
+in leaving "old tasks" completely as is does not seem to be worth it.
+
+I would like to fix the hole in AI-345 soon, so comments on
+any of the above would be appreciated in the near future.
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Tuesday, October 26, 2004  2:48 PM
+
+I like it.
+
+I'm not sure why you want to determine limitedness based only on the
+*first* type.  Using all of them seems cleaner to me.  But I'm not sure
+about that.
+
+I very slightly prefer Root_XXX to XXX_Root.  No big deal.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, October 27, 2004  9:41 PM
+
+> John and Pascal have noticed a hole in the wording for
+> AI-345 where we don't clearly indicate the intent that
+> a nonlimited type may implement a limited interface.
+> This leads to the question of what determines whether
+> a derived type declared with one or more limited interface
+> ancestors is limited or nonlimited.  The simplest rule
+> is that a derived type is nonlimited if at least one
+> of its ancestors is nonlimited.
+
+That seems fine.
+
+...
+> This naturally led me to thinking about an even more polymorphic
+> list, presuming we had a limited interface which every
+> tagged type, whether limited or non-limited, was considered
+> a descendant.  The same could go for synchronized, protected,
+> and task.  This led me to something like:
+>
+>      package Ada.Roots is
+>         type Limited_Root is limited interface;
+>         type Nonlimited_Root is interface and Limited_Root;
+>         type Synchronized_Root is synchronized interface and Limited_Root;
+>         type Task_Root is task interface and Synchronized_Root;
+>         type Protected_Root is protected interface and Synchronized_Root;
+>      end Ada.Roots;
+>
+> I suppose all of these names could be inverted, producing
+> "Root_Limited," "Root_Nonlimited", etc., but since "limited,"
+> "synchronized", and "protected" are clearly adjectives, I
+> somewhat preferred the above order.
+>
+> In any case, the important point is that *all* tagged types
+> would be considered to be covered by Limited_Root'Class,
+> all nonlimited tagged types would be covered by Nonlimited_Root'Class,
+> all protected types would be covered by Protected_Root'Class,
+> and all task types would be covered by Task_Root'Class.
+>
+> In addition to "solving" the problem with a nonlimited
+> type with only limited interface ancestors, having these
+> root interfaces could be quite useful.  Most O-O languages
+> have a root type, often called "Object."  This can be
+> quite useful, and perhaps adding something like this should
+> be considered part of the Ada 2005 "rounding out" of the
+> O-O model.  Note that allowing extensions at a nested scope
+> helps make this possible.
+
+This seems interesting at first, until you start thinking about how this
+could be used. Since there aren't any operations, there really isn't
+anything useful that could be done with an object of Limited_Root'Class. It
+doesn't have any operations or components! All you could do is test its type
+and then convert it to some other type. That's awful O-O programming
+(because it's not extensible) - it's just like a giant case statement.
+
+Most O-O languages have some operations on their root type (like streaming,
+hashing, etc.) that make this more interesting (because there are useful
+things that you can do with the type).
+
+Anyway, it seems pretty late for such a change, especially as we considered
+something on this line (but not as ambitious) before and rejected it.
+
+> Having these might also simplify the creation of something like
+> the "generic constructor" we have proposed.
+
+I don't see how. The operations are the key to that, and there aren't any
+operations here.
+
+...
+> A second point -- if we add these "root" types I would simplify
+> the rules for task and protected types and make them *all*
+> treated as "synchronized tagged" types, independent of whether they
+> have an explicit interface as an ancestor.  Currently, only if
+> a task or protected type has an interface ancestor can you use the
+> 'Tag attribute with it.  The thought was that perhaps this would
+> provide a smoother transition from Ada 95, but having a "Task_Root"
+> interface seems so useful, that whatever marginal value there is
+> in leaving "old tasks" completely as is does not seem to be worth it.
+
+You'd have to do that, or you won't be able to treat an ordinary task object
+as a member of Limited_Root'Class.
+
+> I would like to fix the hole in AI-345 soon, so comments on
+> any of the above would be appreciated in the near future.
+
+Gotcha.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, October 29, 2004  7:02 AM
+
+> >      package Ada.Roots is
+> >         type Limited_Root is limited interface;
+> >         type Nonlimited_Root is interface and Limited_Root;
+> >         type Synchronized_Root is synchronized interface
+> and Limited_Root;
+> >         type Task_Root is task interface and Synchronized_Root;
+> >         type Protected_Root is protected interface and
+> Synchronized_Root;
+> >      end Ada.Roots;
+
+I agree with Randy's comments on this idea.  I'd like to add two things:
+
+I fear that by introducing the fiction that all types are derived from an
+interface, we would impose a distributed overhead on implementations.  If
+all tasks must have the baggage associated with an interface, that can be
+a problem.  Another example is that interfaces don't work well with
+user-defined tag placement, and we don't want to make user-defined tag
+placement invalid for existing tagged types.
+
+Also, interfaces have the nasty "no hidden derivation" rule.  If I have a
+limited private type that is implemented by a nonlimited type, is the full
+view derived from Nonlimited_Root?  Does that mean that the partial view
+has to be derived from Nonlimited_Root too?  One would assume that this
+would be necessary if Nonlimited_Root has any primitive operation ("="
+comes to mind).
+
+While it is clear that we need an answer to the question of how
+limitedness of interfaces carries to concrete types, Tuck's proposal
+doesn't seem like the most productive approach to me.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, October 29, 2004  8:28 AM
+
+> I fear that by introducing the fiction that all types are derived from an
+> interface, we would impose a distributed overhead on implementations.  If
+> all tasks must have the baggage associated with an interface, that can be
+> a problem.  Another example is that interfaces don't work well with
+> user-defined tag placement, and we don't want to make user-defined tag
+> placement invalid for existing tagged types.
+
+Can you remind me of the problem?  If you have user-defined tag placement,
+couldn't you just provide a dispatching version of "'Tag" in the same
+way we have dispatching versions of "'Size" for classwide_obj'Size?
+
+>
+> Also, interfaces have the nasty "no hidden derivation" rule.  If I have a
+> limited private type that is implemented by a nonlimited type, is the full
+> view derived from Nonlimited_Root?  Does that mean that the partial view
+> has to be derived from Nonlimited_Root too?  One would assume that this
+> would be necessary if Nonlimited_Root has any primitive operation ("="
+> comes to mind).
+
+I think we should probably refine the "no hidden derivation" rule anyway.
+What we really care about is that for types that can be extended *and*
+that have an interface with at least one primitive operation, we want
+such interfaces to be visible.  If the type can't be extended (e.g.
+it is a task or protected type, or is not visibly tagged), or if the
+interface has no primitives, then there is no reason to impose this rule.
+
+You bring up the Nonlimited_Root which would have "=" (and ":=").
+We don't want that to be hidden, I agree.  But we already require that
+a limited tagged private type be implemented by a limited full type.
+There are good reasons for that (you don't want a root-type's non-limitness
+to be hidden, since then extenders might add uncopyable component's in
+an extension part).
+
+Certainly a non-tagged private type need not advertise that its
+full type (implicitly) implements some interface, since it can't
+be extended anyway.
+
+> While it is clear that we need an answer to the question of how
+> limitedness of interfaces carries to concrete types, Tuck's proposal
+> doesn't seem like the most productive approach to me.
+
+I would like you to reconsider.  It is clear that having a Task_Root
+would be useful, as it would remove a lot of the need for the
+Task_Identity kludges.  Having a Nonlimited_Root solves the problem
+of defining a non-limited type with only limited interface ancestors,
+and also is useful, since it has the "=" and ":=" operations.
+Admittedly Limited_Root is not very useful, but it does provide
+an ability to create completely polymorphic structures, which despite
+concerns about violating "good" O-O style, can still be useful,
+for example when doing storage management, and wanting to maintain
+a list of all allocated objects.  Clearly 'Size would still work
+on Limited_Root'Class.
+
+Even O-O languages that have generics have still found having a type
+that represents the overall "root" of the extendable type hierarchy
+is useful.  You could define non-generic interfaces for "magic" builtin
+operations such as "hash" or "image" which implementations might want
+to provide, or which we might want to standarize some day.  Or we
+could add overridable primitives to these root types some day for
+similar purposes.  I think as we look toward the next 10 years, we
+have the goal of making sure the language is flexible and extensible,
+and will compete well with other O-O languages.  Having these root
+types could be seen as "rounding" out the O-O capabilities, and
+having useful distinctions such as Synchronized_Root or Task_Root
+would give Ada a leg up in this area over languages like Java which
+don't really deal with multi-thread sychronization in a clean, safe way.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, October 29, 2004  8:42 AM
+
+> Can you remind me of the problem?  If you have user-defined tag placement,
+> couldn't you just provide a dispatching version of "'Tag" in the same
+> way we have dispatching versions of "'Size" for classwide_obj'Size?
+
+I'll answer my own question:  Duh.  No, you can't dispatch
+without knowing where the tag is.  So a dispatching version
+of 'Tag doesn't make any sense.  One thing you
+could do is have a dispatching version of "'Address" which
+would require that you pass a pointer to the word containing
+the tag, but you could dispatch to find out where the object
+actually "started" if the tag wasn't the first word of the object.
+
+That might actually work.
+
+I hate to have user-defined tag placement derail interesting
+ideas, unless it is really an important capability.  Do you
+have any idea how often and for what purpose it is used?
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, October 29, 2004  9:01 AM
+
+> Can you remind me of the problem?  If you have user-defined
+> tag placement, couldn't you just provide a dispatching
+> version of "'Tag" in the same way we have dispatching
+> versions of "'Size" for classwide_obj'Size?
+
+Say that type T implements interface I, and the tag of T is placed at
+offset 40.  When you convert an object of type T to type I, how does the
+interface know where the tag is located?  I seem to remember that your
+compiler does not support user-defined tag placement, but others do, and
+this is not a capability we can afford to lose.  It's one thing to say "if
+you use interfaces, say goodbye to tag placement".  It's a totally
+different thing to say "you are always using interfaces implicitly, so no
+tag placement in Ada 2005".
+
+> If the type can't be extended (e.g.
+> it is a task or protected type, or is not visibly tagged), or
+> if the interface has no primitives, then there is no reason
+> to impose this rule.
+
+I agree that it makes sense to relax the rule for types that cannot be
+extended.  I am not convinced that it is a good idea to special-case the
+interface that has no primitive.  It seems like a maintenance headache to
+me (add a primitive, and your architecture need extensive surgery).
+
+> I would like you to reconsider.  It is clear that having a
+> Task_Root would be useful, as it would remove a lot of the
+> need for the Task_Identity kludges.
+
+Hardly a convincing argument.  Attribute Identity is here to stay, so to
+take advantage of the Task_Root interface, we would need to provide a
+second mechanism to name tasks.  That would increase confusion.
+
+> Having a Nonlimited_Root
+> solves the problem of defining a non-limited type with only
+> limited interface ancestors, and also is useful, since it has
+> the "=" and ":=" operations.
+
+Hardly a convincing argument, again.  If we are trying to solve the
+problem of defining a non-limited type with only limited interface
+ancestors, all we need to do is to provide somewhere a nonlimited
+interface.  We don't have to say that all nonlimited types implement that
+interface.
+
+> Even O-O languages that have generics have still found having
+> a type that represents the overall "root" of the extendable
+> type hierarchy is useful.
+
+Not all OO languages are like that (think of C++).  I guess I have never
+seen this approach as very elegant language design.  When your only
+abstraction mechanism is inheritance, you tend to solve all problems in
+terms of inheritance.
+
+--
+
+Couldn't we simply say that a type whose parents are all interfaces does
+not inherit limitedness, but that limitedness must be explicitly
+specified?  After all that's what we do for task and protected types: you
+have to repeat "task" or "protected", even if you ancestors are all task
+or protected interfaces.  Thus, if I1, I2, I3 are limited interfaces, then
+in the following declarations:
+
+	type T1 is new I1 and I2 and I3 with ...;
+	type T2 is limited new I1 and I2 and I3 with ...;
+
+type T1 is nonlimited and type T2 is limited.  The second form would of
+course be illegal if any of the interfaces is nonlimited.  We could even
+allow repeating "limited" if the first ancestor is a noninterface limited
+type, just for documentation.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, October 29, 2004  9:12 AM
+
+> I'll answer my own question:  Duh.  No, you can't dispatch
+> without knowing where the tag is.  So a dispatching version
+> of 'Tag doesn't make any sense.  One thing you could do is
+> have a dispatching version of "'Address" which would require
+> that you pass a pointer to the word containing the tag, but
+> you could dispatch to find out where the object actually
+> "started" if the tag wasn't the first word of the object.
+
+There's no problem that cannot be solved with a level of indirection ;-)
+
+> I hate to have user-defined tag placement derail interesting
+> ideas, unless it is really an important capability.  Do you
+> have any idea how often and for what purpose it is used?
+
+I don't remember the details now, but when we didn't support this, we had
+customers clamoring for it.  Not to mention that many compilers support it
+in one way or another.  I think that users just want to get the tag out of
+the way.  Maybe the Master of Claw can provide more information.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, October 29, 2004  9:23 AM
+
+> I agree that it makes sense to relax the rule for types that cannot be
+> extended.  I am not convinced that it is a good idea to special-case the
+> interface that has no primitive.  It seems like a maintenance headache to
+> me (add a primitive, and your architecture need extensive surgery).
+
+In Java, there are several operation-less interfaces which are
+used as "indicators."  I'm not sure whether that would become a
+common paradigm in Ada, but if it did, it would seem that it
+would be reasonable for such indicators to be private if desired.
+
+I think going from an interface without operations to one
+with would require extensive surgery any way you "slice" it. ;-)
+
+
+> Couldn't we simply say that a type whose parents are all interfaces does
+> not inherit limitedness, but that limitedness must be explicitly
+> specified?  After all that's what we do for task and protected types: you
+> have to repeat "task" or "protected", even if you ancestors are all task
+> or protected interfaces.  Thus, if I1, I2, I3 are limited interfaces, then
+> in the following declarations:
+>
+> 	type T1 is new I1 and I2 and I3 with ...;
+> 	type T2 is limited new I1 and I2 and I3 with ...;
+>
+> type T1 is nonlimited and type T2 is limited.  The second form would of
+> course be illegal if any of the interfaces is nonlimited.  We could even
+> allow repeating "limited" if the first ancestor is a noninterface limited
+> type, just for documentation.
+
+This seems like a viable idea.  I might recommend placing the "limited"
+next to the word "private" or "record" rather than next to new, since
+"limited" comes after "tagged" now, and moving it to the front here
+might cause "cognitive dissonance" for users.  Hence:
+
+     type T1 is new I1 and I2 and I3 with [limited] private/record/null record;
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Friday, October 29, 2004  9:33 AM
+
+> I hate to have user-defined tag placement derail interesting
+> ideas, unless it is really an important capability.  Do you
+> have any idea how often and for what purpose it is used?
+
+Is there an issue with interface to C++?
+
+Pascal wrote:
+
+> Not all OO languages are like that (think of C++).  I guess I have never
+> seen this approach as very elegant language design.
+
+I find it quite elegant, for what that's worth.  I find the Ada/C++
+approach, where there's no way to talk about the "root of everything" to
+be the kludgy one.  I doubt if I can convince you on a matter of taste
+like this, but let me try this analogy: we have a "root of everything"
+in the package hierarchy (package Standard).  Do you find *that* to be
+inelegant language design?  How about the environment task, which is the
+root of the task hierarchy?  In general, it seems to me that hierarchies
+should have roots.
+
+>...We could even
+> allow repeating "limited" if the first ancestor is a noninterface limited
+> type, just for documentation.
+
+I don't much like giving programmers such choices.  If a programmer gets
+used to seeing "limited" where it's optional, they will be confused when
+they run across code written in the other style.  Whatever is not
+forbidden should be required.  ;-)  (And Jean Ichbiah should have decided
+whether 'in' should be explicit or implicit in parameter decls, rather
+than leaving it up to programmers.)
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Friday, October 29, 2004  9:42 AM
+
+> type T1 is new I1 and I2 and I3 with [limited] private/record/null record;
+
+That syntax seems odd to me.  You're not adding a limited extension.
+You're saying that the whole thing is limited.  I prefer Pascal's syntax
+if we go that way.
+
+However, I still prefer making it implicitly limited, because that's how
+the old-style tagged types work (they inherit limitedness).  So I think
+this new syntax (either yours or Pascal's) will add confusion.  So to
+make it nonlimited, you would have to inherit from Root_Nonlimited, as
+you suggested at first.
+
+And I still think having everything derived from Root_Task and
+Root_Limited and so forth is a good idea -- if we can figure out
+how to make it work (re: tag placement).
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Friday, October 29, 2004 10:04 AM
+
+If you are polling opinions, I don't like the "big root" concept. A
+principle of OO is that classes gather objects that have common
+properties. "Object" gathers all objects that have no common properties.
+   A typical case where Robert would remind you that "to confuse" has
+two meanings...
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, October 29, 2004 10:25 AM
+
+> If you are polling opinions, I don't like the "big root" concept. A
+> principle of OO is that classes gather objects that have common
+> properties. "Object" gathers all objects that have no common properties.
+
+In this case, Limited_Root are the types that have tags.
+Perhaps it would be better called "Tagged_Root."
+All the other proposed "roots" clearly indicate common properties.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, October 29, 2004 10:21 AM
+
+> I find it quite elegant, for what that's worth.  I find the
+> Ada/C++ approach, where there's no way to talk about the
+> "root of everything" to be the kludgy one.  I doubt if I can
+> convince you on a matter of taste like this, but let me try
+> this analogy: we have a "root of everything"
+> in the package hierarchy (package Standard).  Do you find
+> *that* to be inelegant language design?  How about the
+> environment task, which is the root of the task hierarchy?
+> In general, it seems to me that hierarchies should have roots.
+
+Actually, I would be happier if there was no package Standard, and if all
+types were user-defined.  This is not quite feasible with Boolean and
+Character, but I certainly think that having predefined integer and float
+types was a mistake.
+
+The "root of everything" approach reminds me of Smalltalk's "everything is
+an object" mantra.  Sorry, I could never believe that the best
+representation of an integer was an object to whom you would send the
+"addition" message.  Similarly the hierarchies of C++/Java/etc. force the
+notion that things like streaming, hashing, etc. are relevant to all
+objects, which is generally false (in a typical application, you only
+stream or hash a minority of the types).
+
+As you said, this is a matter of taste in the end.  Consider this,
+however: Smalltalk, Java and C++ do not have entire communities that make
+heavy use of the language without ever using a tagged type or an
+interface.  I don't think the real-time/safety-critical community would be
+very happy to get interfaces in every task or protected object.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, October 29, 2004 10:27 AM
+
+> However, I still prefer making it implicitly limited, because
+> that's how the old-style tagged types work (they inherit
+> limitedness).  So I think this new syntax (either yours or
+> Pascal's) will add confusion.  So to make it nonlimited, you
+> would have to inherit from Root_Nonlimited, as you suggested at first.
+
+It seems to me that in real life most interfaces will be limited (as a
+matter of fact I cannot think of many interfaces that would only make
+sense in the presence of assignment) and many concrete types will be
+nonlimited (replace many by most if we don't do a good job of fixing
+limited types).
+
+You are asking me to add "Ada.Roots.Root_Nonlimited and" to most type
+declarations that make use of interface.  So much for readability!  And of
+course, so much for the notion that simple things should be simple,
+complex things should be possible.
+
+****************************************************************
+
+From: Steve Michell
+Sent: Friday, October 29, 2004 11:29 AM
+
+> As you said, this is a matter of taste in the end.  Consider this,
+> however: Smalltalk, Java and C++ do not have entire communities that make
+> heavy use of the language without ever using a tagged type or an
+> interface.  I don't think the real-time/safety-critical community would be
+> very happy to get interfaces in every task or protected object.
+>
+
+I think that this is a red herring Pascal. Tasks and Protected Objects already
+clearly have a common root which contains the Task_Id, priority, runtime state
+for tasks and some kind of ID, ceiling priority, lock and queues for a PO.
+Creating a common root to support interfaces does nothing new.
+
+On the other hand, to be acceptable to these communities, interfaces must be a
+compile-only characteristic with no runtime effects.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, October 29, 2004  12:50 PM
+
+But the entire point of making things tagged is that it has a runtime
+effect. That is, it has a tag that can be queried and the like. And it would
+be necessary to be able to upconvert from Task_Root'Class to some specific
+type.
+
+Moreover, implementations could define Task_Root'Class operations. (Users
+couldn't usefully do so, because they would have no access to any
+commonality.)
+
+So there would be a small runtime effect. One could argue that to the only
+cost if you didn't use Task_Root'Class would be the added tag (and I suppose
+Ravenscar would prohibit using Task_Root'Class or tag operations on a task).
+
+Of course, the problem in my mind is that there are no predefined operations
+for any of these interfaces. That means that nothing useful can be done with
+them; to do anything, you'd have to test for membership and upconvert. And
+if you really needed to do that, you could simply define your own interface
+for the task.
+
+So, in the absense of some operations for these types, it doesn't seem worth
+it to have them. (And I don't think not doing it now would prevent us from
+doing it in the future.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, October 29, 2004  1:37 PM
+
+> But the entire point of making things tagged is that it has a runtime
+> effect. That is, it has a tag that can be queried and the like. And it would
+> be necessary to be able to upconvert from Task_Root'Class to some specific
+> type.
+
+In all implementations I know of, every task and protected object
+has a pointer to some kind of type descriptor.  The issue is
+whether this pointer can be made to look like a "tag".  There
+would be some nice advantages.  For example, you could use
+the operations of Ada.Tags to get an External_Name for the
+task/protected type.  And you could manage sets of tasks of
+any task type with polymorphic lists using Task_Root'Class,
+even if the task wasn't defined explicitly to use a task interface.
+
+I suspect if we *don't* define a Task_Root type, then various
+scheduling packages will appear that define their own Task_Root-like
+interface, and then we will get into the trouble we have had
+with proliferating String_Access types, etc.  Every package
+defines its own Task_Root-like thing, so you may end up having
+battling task-roots, or having to define every task type as
+being derived from multiple task-root-like things.
+
+
+> Moreover, implementations could define Task_Root'Class operations. (Users
+> couldn't usefully do so, because they would have no access to any
+> commonality.)
+
+Why do you say there woudn't be useful functionaliy?  There are
+attributes ('Callable and 'Terminated and 'Identity) and the
+abort statement all of which can be applied to any task-interface
+object as well.
+
+> So there would be a small runtime effect. One could argue that to the only
+> cost if you didn't use Task_Root'Class would be the added tag (and I suppose
+> Ravenscar would prohibit using Task_Root'Class or tag operations on a task).
+
+I don't think you need to add a tag, you just need to make sure that
+your existing task/protected type descriptors are usable as tags.
+
+> Of course, the problem in my mind is that there are no predefined operations
+> for any of these interfaces. That means that nothing useful can be done with
+> them; to do anything, you'd have to test for membership and upconvert. And
+> if you really needed to do that, you could simply define your own interface
+> for the task.
+>
+> So, in the absense of some operations for these types, it doesn't seem worth
+> it to have them. (And I don't think not doing it now would prevent us from
+> doing it in the future.)
+
+Tasks have several language-defined operations, and the point here
+is supporting natural extensibility in the future.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, October 29, 2004  1:43 PM
+
+I would think we might agree that from a safety point of
+view, encouraging users to write packages that take
+Task_Root'Class rather than task-ids is better, since
+you don't have the dangling references implicit in the
+use of task ids.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, October 29, 2004  2:18 PM
+
+> In all implementations I know of, every task and protected object
+> has a pointer to some kind of type descriptor.  The issue is
+> whether this pointer can be made to look like a "tag".
+
+I doubt it very much. A tag is a read-only list of items, while a TCB is a
+dynamic data structure. They're not even in the same logical address space
+(mixing things that change with things that cannot change is what makes most
+of the exploits used today possible). Certainly, it couldn't be done for
+Janus/Ada.
+
+Moreover, it makes no sense to rearrange and rewrite your entire task
+supervisor in order to save the cost of a single tag in the task object! I
+could imagine storing the tag *in* the TCB, but certainly not making the TCB
+directly into the tag.
+
+And in any case, the (small) cost of storing the tag somewhere is not going
+away; it might be in the task object, or in the TCB, or wherever, but it
+certainly isn't going to be free.
+
+> There would be some nice advantages.  For example, you could use
+> the operations of Ada.Tags to get an External_Name for the
+> task/protected type.  And you could manage sets of tasks of
+> any task type with polymorphic lists using Task_Root'Class,
+> even if the task wasn't defined explicitly to use a task interface.
+
+Yes, but you can't do anything useful with those lists.
+
+> I suspect if we *don't* define a Task_Root type, then various
+> scheduling packages will appear that define their own Task_Root-like
+> interface, and then we will get into the trouble we have had
+> with proliferating String_Access types, etc.  Every package
+> defines its own Task_Root-like thing, so you may end up having
+> battling task-roots, or having to define every task type as
+> being derived from multiple task-root-like things.
+
+Yes, because those interfaces will have operations with them that will
+provide some reason for doing this. There is no reason to do this without
+operations.
+
+> > Moreover, implementations could define Task_Root'Class operations. (Users
+> > couldn't usefully do so, because they would have no access to any
+> > commonality.)
+>
+> Why do you say there wouldn't be useful functionality?  There are
+> attributes ('Callable and 'Terminated and 'Identity) and the
+> abort statement all of which can be applied to any task-interface
+> object as well.
+
+You can do those things on any task now, so I don't see any gain. And in any
+case, none of those things are useful anyway. Who cares if a task is
+callable if you have no entries to call? About the only thing you could do
+would be to abort a list of tasks; that's not a large enough gain for making
+a significant last-minute change.
+
+> > Of course, the problem in my mind is that there are no predefined operations
+> > for any of these interfaces. That means that nothing useful can be done with
+> > them; to do anything, you'd have to test for membership and upconvert. And
+> > if you really needed to do that, you could simply define your own interface
+> > for the task.
+> >
+> > So, in the absence of some operations for these types, it doesn't seem worth
+> > it to have them. (And I don't think not doing it now would prevent us from
+> > doing it in the future.)
+>
+> Tasks have several language-defined operations, and the point here
+> is supporting natural extensibility in the future.
+
+The language-defined operations are useless (especially if you have a "no
+abort" policy in place, which many projects do), and can be done anyway.
+There is nothing incrementally added by this proposal that could be possibly
+worthwhile.
+
+I'd rather see this done right, with useful (common) operations defined on
+all of the interfaces. And doing that is a big and likely controversial job.
+An interface without operations is useless, because you can't do anything
+with it.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, October 29, 2004  2:43 PM
+
+The TCB and the task type descriptor are two different things.
+But you are right, most task objects point at a TCB first and
+foremost.  However, either the task object or the TCB sometimes
+also has a pointer to a *type* descriptor (the TCB is per-object,
+the type descriptor is per-type).  The type descriptor might
+have the start address of the task body and other information
+that characterizes the task type as opposed to the task object.
+
+Having a type descriptor is probably more common for a protected
+type, where the address of the various entry bodies might be
+stored.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Friday, October 29, 2004  6:20 PM
+
+>I think that this is a red herring Pascal. Tasks and Protected Objects already clearly
+>have a common root which contains the Task_Id, priority, runtime state for tasks and some
+>kind of ID, ceiling priority, lock and queues for a PO. Creating a common root to support
+>interfaces does nothing new.
+
+Good point.  I think it may be a little late for this big a change in
+the language.  It would certainly clarify/simplify some of the tasking
+packages and features to make the Root_Task (or Task_Root) an explicit type.
+
+But I think that in this case it is awful late for such a change in the
+language, and even later for the more general root types.
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent