CVS difference for ais/ai-00419.txt

Differences between 1.2 and version 1.3
Log of other versions for file ais/ai-00419.txt

--- ais/ai-00419.txt	2005/03/11 21:49:49	1.2
+++ ais/ai-00419.txt	2005/04/13 05:37:24	1.3
@@ -1,4 +1,14 @@
-!standard 3.4(2)                                    05-03-11  AI95-00419-01/02
+!standard 3.4(02)                                    05-03-16  AI95-00419-01/02
+!standard 3.4(05)
+!standard 3.4(15)
+!standard 7.3(02)
+!standard 7.3(06)
+!standard 7.3(08)
+!standard 7.3(10)
+!standard 7.5(02)
+!standard 7.5(04)
+!standard 7.5(06)
+!standard 12.5.1(03)
 !class amendment 05-03-09
 !status Amendment 200Y 05-03-10
 !comment This AI is in the Amendment, but is not yet approved.
@@ -127,12 +137,6 @@
   End AARM.
 
 
-Add at the end of 3.9.4(9) (added by AI95-00251 and AI95-00345):
-
-  In addition to the places where Legality Rules normally apply (see 12.3),
-  these rules apply also in the private part of an instance of a generic unit.
-
-
 Change 7.3(3) as amended by AI95-0251 to read:
 
 private_extension_declaration ::=
@@ -146,8 +150,7 @@
 Redundant[A private type is limited if its declaration includes the reserved
 word *limited*; a private extension is limited if its ancestor type is a
 limited type that is not an interface type, or if the reserved word *limited*
-appears in its definition.] If the partial view is nonlimited, then the full
-view shall be nonlimited.
+appears in its definition.]
 
 
 Add after 7.3(8):
@@ -173,11 +176,14 @@
 Redundant[and any progenitor interfaces] shall be limited.
 
 
-Change 7.5(4) to read:
+Change 7.5(3-6) to read: (This includes the change of AI-411):
 
-o a type which is not an interface type and has the reserved word *limited* in
-its definition;
+A type is limited if it is one of the following:
 
+*  A type with the reserved words *limited*, *synchronized*, *task* or
+   *protected* in its definition;
+*  A composite type with a limited component;
+*  A derived type whose parent is limited and is not an interface.
 
 Change 12.5.1(3) as amended by AI95-00251 to read:
 
@@ -191,13 +197,1536 @@
 
 !example
 
+(See proposal.)
+
+!corrigendum 3.4(02)
+
+@drepl
+@xcode<@fa<derived_type_definition ::= [>@ft<@b<abstract>>@fa<] >@ft<@b<new> @i<parent_>>@fa<subtype_indication [record_extension_part]>>
+@dby
+@xcode<@fa<interface_list ::= >@ft<@i<interface_>>@fa<subtype_mark {>@ft<@b<and>>@fa< >@ft<@i<interface_>>@fa<subtype_mark}>>
+
+@xcode<@fa<derived_type_definition ::=
+    [>@ft<@b<abstract>>@fa<] [>@ft<@b<limited>>@fa<] >@ft<@b<new> @i<parent_>>@fa<subtype_indication [[>@ft<@b<and>>@fa< interface_list] record_extension_part]>>
+
+
+!corrigendum 3.4(05)
+
+@dinsa
+If there is a @fa<record_extension_part>, the derived type is called a
+@i<record extension> of the parent type. A @fa<record_extension_part> shall be
+provided if and only if the parent type is a tagged type.
+@dinst
+If the reserved word @b<limited> appears in a @fa<derived_type_definition>, the
+parent type shall be a limited type.
+
+
+!corrigendum 3.4(15)
+
+@drepl
+@xbullet<The derived type is limited if and only if the parent type is limited.>
+@dby
+@xbullet<The derived type is limited if the parent is a limited type that is not an interface type, or if the reserved word @b<limited> appears.>
+
+
+!corrigendum 7.3(02)
+
+@drepl
+@xcode<@fa<private_extension_declaration ::=
+   >@ft<@b<type>>@fa< defining_identifier [discriminant_part] >@ft<@b<is>>@fa<
+     [>@ft<@b<abstract>>@fa<] >@ft<@b<new>>@fa< ancestor_subtype_indication >@ft<@b<with private>>@fa<;>>
+@dby
+@xcode<@fa<private_extension_declaration ::=
+   >@ft<@b<type>>@fa< defining_identifier [discriminant_part] >@ft<@b<is>>@fa<
+     [>@ft<@b<abstract>>@fa<] [>@ft<@b<limited>>@fa<] >@ft<@b<new>>@fa< ancestor_subtype_indication [>@ft<@b<and>>@fa< interface_list] >@ft<@b<with private>>@fa<;>>
+
+
+!corrigendum 7.3(06)
+
+@drepl
+A private type is limited if its declaration includes the reserved word
+@b<limited>; a private extension is limited if its ancestor type is limited. If
+the partial view is nonlimited, then the full view shall be nonlimited. If a
+tagged partial view is limited, then the full view shall be limited. On the
+other hand, if an untagged partial view is limited, the full view may be
+limited or nonlimited.
+@dby
+A private type is limited if its declaration includes the reserved
+word @b<limited>; a private extension is limited if its ancestor type is a
+limited type that is not an interface type, or if the reserved word @b<limited>
+appears in its definition. If the partial view is nonlimited, then the full
+view shall be nonlimited. If a tagged partial view is limited, then the full
+view shall be limited. On the other hand, if an untagged partial view is
+limited, the full view may be limited or nonlimited.
+
+
+!corrigendum 7.3(08)
+
+@dinsa
+The @i<ancestor subtype> of a @fa<private_extension_declaration> is the subtype
+defined by the @fa<ancestor_subtype_indication>; the ancestor type shall be a
+specific tagged type. The full view of a private extension shall be derived
+(directly or indirectly) from the ancestor type. In addition to the places
+where Legality Rules normally apply (see 12.3), the requirement that the
+ancestor be specific applies also in the private part of an instance of a
+generic unit.
+@dinst
+If the reserved word @b<limited> appears in a
+@fa<private_extension_declaration>, the ancestor type shall be a limited type.
+
+
+!corrigendum 7.3(10)
+
+@dinsa
+If a private extension inherits known discriminants from the ancestor subtype,
+then the full view shall also inherit its discriminants from the ancestor
+subtype, and the parent subtype of the full view shall be constrained if and
+only if the ancestor subtype is constrained.
+@dinst
+If the full view of a private extension is limited, then the reserved word
+@b<limited> shall appear in the @fa<full_type_declaration> if and only if it
+also appears in the @fa<private_extension_declaration>.
+
+
+!corrigendum 7.5(02)
+
+@drepl
+If a tagged record type has any limited components, then the reserved word @b<limited> shall appear in its @fa<record_type_definition>.
+@dby
+If a tagged record type has any limited components, then the reserved word
+@b<limited> shall appear in its @fa<record_type_definition>. If the reserved
+word @b<limited> appears in the definition of a type extension, its parent type
+and any progenitor interfaces shall be limited.
+
+
+!corrigendum 7.5(03)
 
---!corrigendum
+@drepl
+A type is @i<limited> if it is a descendant of one of the following:
+@dby
+A type is @i<limited> if it is one of the following:
 
+!corrigendum 7.5(04)
+!Comment note that the rewrite of this list eliminates the AI-411 change.
+
+@drepl
+@xbullet<a type with the reserved word @b<limited> in its definition;>
+@dby
+@xbullet<a type with the reserved word @b<limited>, @b<synchronized>,
+@b<task>, or @b<protected> in its definition;>
+
+!corrigendum 7.5(05)
+
+@ddel
+@xbullet<a task or protected type;>
+
+!corrigendum 7.5(06)
+
+@drepl
+@xbullet<a composite type with a limited component.>
+@dinst
+@xbullet<a composite type with a limited component;>
+
+@xbullet<a derived type whose parent is limited and is not an interface.>
+
+!corrigendum 12.5.1(03)
+
+@drepl
+@xcode<@fa<formal_derived_type_definition ::= [>@ft<@b<abstract>>@fa<] >@ft<@b<new>>@fa< subtype_mark [>@ft<@b<with private>>@fa<]>>
+@dby
+@xcode<@fa<formal_derived_type_definition ::=
+     [>@ft<@b<abstract>>@fa<] [>@ft<@b<limited>>@fa<] >@ft<@b<new>>@fa< subtype_mark [[>@ft<@b<and>>@fa< interface_list] >@ft<@b<with private>>@fa<]>>
+
+
 !ACATS test
 
 ACATS tests should be constructed to test the legality rules here.
 
 !appendix
 
+From: Tucker Taft
+Sent: Thursday, February 17, 2005  3:31 AM
+
+I had a grab-bag of morning after thoughts
+after the Paris ARG meeting.  (Unfortunatly, that
+meant I didn't get much sleep on the overnight
+train to Tignes. ;-)  I'll mention just the first two
+in this e-mail, since I am running out of time
+before I have to zip off to the airport.
+
+-----------------
+
+1) There seems no reason we can't "hide" the
+fact that a type implements an interface, so long
+as the interface has no user-defined primitive
+subprograms.  In some ways, this is analogous to
+hiding the fact that a type is nonlimited, if
+we think of "nonlimitedness" as being an interface
+with ":=" and "=".
+
+2) I am concerned about the rule that if you
+have a type that should be nonlimited, but also
+needs to implement one or more limited interfaces,
+that you have to concoct an "artificial" nonlimited
+parent type or interface.  One possibility that
+popped into my head was:
+
+     type T is not limited and Int1 and Int2 with ...
+
+This way the type can implement some limited interfaces without
+having to specify a nonlimited parent.  This syntax
+also suggests a similar solution for partial views
+of tasks and protected types that implement interfaces:
+
+     type TT is task and Int1 and Int2 with private;
+     type PT is protected and Int1 and Int2 with private;
+
+And for completeness, and also to make the fact that a type
+is "limited" clear:
+
+     type LT is limited and Int1 and Int2 with ...
+
+and at which point we might as well allow
+
+     type ST is synchronized and Int1 and Int2 with private;
+
+Hence the overall syntax would be approximately:
+
+     type <identifier>[<discrim_part>] is
+       <kind> and <interface_list> with ...
+
+     <kind> ::= [not] limited | task | protected | synchronized
+
+This syntax would only be permitted when there is an interface_list,
+as a way to specify the kind of the type without having to rely
+on there being an interface that has that same kind.
+
+My biggest fear is that there will be a proliferation of
+silly interfaces just to provide parent types when wanting
+to make a type nonlimited, or indicate that a generic formal
+type is a task, etc.  Having a proliferation of these will
+make integration across independently developed subsystems
+that much harder, and is worse than the similar situation
+with access types, since we have said there may be no
+hidden interfaces.  Note that idea (1) above is a partial
+solution to this problem, but I still think the proliferation
+will be nasty.  I also think the added documentation of
+specifying "not limited" or "limited" explicitly will
+be an advantage.
+
+More later ;-)
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Thursday, February 17, 2005  7:59 AM
+
+> 1) There seems no reason we can't "hide" the
+> fact that a type implements an interface, so long
+> as the interface has no user-defined primitive
+> subprograms.  In some ways, this is analogous to
+> hiding the fact that a type is nonlimited, if
+> we think of "nonlimitedness" as being an interface
+> with ":=" and "=".
+
+Hmm.  I wouldn't be so optimistic.
+
+In the case of nonlimited interfaces, it seems to me that at a minimum you
+would not want to hide the nonlimitedness.  In other words, the following
+should be illegal:
+
+	type I is interface;
+
+	package P is
+	   type T is tagged limited private;
+	private
+	   type T is new I with null record;
+	end P;
+
+If it is not illegal, clients of P can derive from P.T and redefine "=",
+and we would end up with the same situation as described in the AARM note
+of AI 396, where the client ends redefine an operation that they don't
+know about, or where the type ends up with two distinct "=" operators. In
+the case of limited interfaces, you have to deal with the compatibility
+rules between task and protected interfaces.  For example:
+
+	type TI is task interface
+
+	package P is
+	   type T is tagged limited private;
+	private
+	   type T is new TI with null record;
+	end P;
+
+	type PI is protected interface;
+	type T2 is new P.T with PI and null record; -- Legal
+
+One hope that the declaration of type T2 is illegal, because there is no
+way that a type can implement both a task interface and a protected
+interface, but of course this leads to a privacy violation.
+
+I suppose the idea could be made to work with appropriate restrictions,
+but it's probably not worth the effort.  I for one cannot get excited
+about interfaces which have no user-defined subprograms.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, February 17, 2005  11:30 AM
+
+I would go further and say that a type with no subprograms and no components
+is next to useless. The mostly likely place for them to show up would be
+prototyping, and you wouldn't be doing anyone any favors by allowing them in
+places that would become illegal when the subprograms are later added to the
+interface.
+
+So I suggest that Tuck get some sleep rather than worrying about these
+ideas. :-)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 17, 2005  4:06 PM
+
+These are used pretty heavily in Java, as a run-time testable
+property of a type.  E.g. Cloneable, Serializable, EventListener.
+They are called "marker" interfaces, in one article I found.
+
+I think they might turn out to serve a similar purpose in
+Ada, and if so, we wouldn't want to place unnecessary requirements
+on them such as requiring them to be visible in all cases.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, February 17, 2005  5:59 PM
+
+I don't see how the latter follows the former. I'm strongly opposed to rules
+that depend on the shapes of types, whether there are components or
+interfaces, the phase of the moon, or anything else that is easy to change.
+Those are maintenance bombs waiting to happen. I still oppose AI-391 (not
+sure why I didn't vote against it), and I'll oppose this, too.
+
+The model of interfaces is that it doesn't matter where in the hierarchy
+they are added. That makes them fundamentally privacy-breaking, and the rule
+that requires them to be visible for tagged types eliminates problems. If we
+go away from that, we'll have to revisit lots of things (like the
+Interface_Ancestor_Tags function we added last week), because they wouldn't
+be meaningful.
+
+I also do not see how this could work in Ada. (I don't see how it could work
+in any language, for that matter, that claims to have strong typing.) The
+only possible thing that you could do is test for membership, as there are
+no operations to dispatch to. (That's already very dubious from an O-O
+perspective, but let's not go there.) You can't even say "Foobar in
+Serializable", because both operands have to be class-wide before you are
+even allowed to combine them. You would have to say "Foobar in
+Serializable'Class", which is bizarre, since there would never be an
+interface descended from Serializable for this use. And once that proved to
+be true, what could you do? Absolutely nothing, unless you use this to
+assume some implementation in terms of predefined operations. "Serializable"
+is an example; presumably it means that the type has 'Read and 'Write; but
+the language already handles that in a variety of ways. A further marker
+isn't needed in this particular case.
+
+I certainly see no reason to copy hair-brained ideas from Java; Ada can (and
+does) do this stuff so much better. If all we're trying to do is clone Java,
+count me out.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, February 18, 2005  3:27 AM
+
+Tuck wrote:
+
+> These are used pretty heavily in Java, as a run-time testable
+> property of a type.  E.g. Cloneable, Serializable,
+> EventListener. They are called "marker" interfaces, in one
+> article I found.
+
+I see this as poor design on the part of the Java folks, and I don't
+understand why we would want to replicate it in Ada.
+
+Take for instance Cloneable.  The Java hierarchy is such that Object (the
+root of everything) has a clone method.  But for some classes clone
+doesn't make sense.  So they add a class Cloneable that is just a marker
+(I have seen this called a tagging interface, too), and the method clone
+raises an exception for all classes that don't implement Cloneable, and no
+others.
+
+Yuck.  Someone was terribly confused when they decided to provide clone at
+the Object level.
+
+Note that .Net has a structure that I find much cleaner: the interface
+ICloneable has a single method, Clone, and you inherit Clone iff you
+implement ICloneable.  No cheesy exceptions, membership tests, etc.
+
+Serializable has similar semantics.  I didn't check the others, but it
+certainly seems like this "tagging" mechanism is widely (mis)used in Java.
+
+Of course, in Ada Cloneable is spelled "nonlimited" and Serializable is
+spelled "stream-oriented attributes are available" so for these two
+particular interfaces we have support hard-wired in the language.
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Friday, February 18, 2005  4:03 AM
+
+[...]
+I strongly support that view. I always claimed that this use of
+interfaces was a kludge, used only for "magic" interfaces that were
+recognized specially by the language.
+
 ****************************************************************
+
+From: Pascal Leroy
+Sent: Thursday, February 17, 2005  8:15 AM
+
+> 2) I am concerned about the rule that if you
+> have a type that should be nonlimited, but also
+> needs to implement one or more limited interfaces,
+> that you have to concoct an "artificial" nonlimited
+> parent type or interface.
+...
+
+We discussed something like that in the past, and one Tucker Taft was not
+exactly enthusiastic.  See the mail dated October 29 in AI 345.
+
+I am not at all opposed to a syntax like the above, as it's clear that
+making the first interface "special" is somewhat unpleasant.  However, I
+am going to insist that whatever syntax we choose include the word "new"
+somewhere, as we are really writing type derivations.  We want to make
+sure that the syntax clearly distinguishes an interface declaration like:
+
+	type I is I1 and I2 and I3;
+
+from a "normal type" declaration like:
+
+	type T is new I1 and I2 and I3 with ...;
+
+When I look at the syntax above, it's not clear to me if you are declaring
+bona fide types or mere interfaces.
+
+Oh, and I hate to mention this, but it's awfully late.  At this point the
+only part of the core language that you should be changing is AI 416...
+
+****************************************************************
+
+From: Robert Eachus
+Sent: Thursday, February 17, 2005  3:51 PM
+
+I agree that it is almost certainly too late to entertain a change in
+the syntax of this magnitude.  However, I think that
+a legality rule should fix the problem.  If a type which inherits
+interfaces is not declared limited, it is not limited.  Add that
+if a rule that says that a type which inherits from an interface which
+must be limited (such as a synchronized interface) must be declared limited.
+
+Now in the example above,
+    type T is limited and Int1 and Int2 with...
+is a limited type, and
+    type T is Int1 and Int2 with...
+*if legal*, is a non-limited type.
+
+Now you get down to the real issue, when can an interface declared as
+limited be inherited by a non-limited type?  I think the rule has to be
+that if public interface is a task, protected or synchronized interface,
+a non-limited type or interface can't inherit it. It probably makes
+sense in that case to say that interfaces derived from task, protected,
+or synchronized interfaces must either be declared to be of the same
+class or (the more general) synchronized.
+
+So why have limited interfaces in the first place?  Because there are
+cases where you want to declare an interface that doesn't require
+assignment and equality.  There is no reason to prevent such interfaces
+from being inherited by non-limited types.  But the task, protected, and
+synchronized interface declarations make no sense if implemented by a
+type with copying permitted.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 17, 2005  4:13 PM
+
+> We discussed something like that in the past, and one Tucker Taft was not
+> exactly enthusiastic.  See the mail dated October 29 in AI 345.
+
+I admit my view has changed (that's why it is called "morning
+after" ;-).  In examples, I have been bumping into this
+requirement to have a "bogus" parent type just to avoid
+having the new type end up limited if it wants to implement
+a limited interface.
+
+>
+> I am not at all opposed to a syntax like the above, as it's clear that
+> making the first interface "special" is somewhat unpleasant.  However, I
+> am going to insist that whatever syntax we choose include the word "new"
+> somewhere, as we are really writing type derivations.
+
+I guess I was somewhat attracted to the idea these were *not*
+like type derivations, in that they aren't inheriting code or components
+from anything.  They are simply "promising" to implement one or
+more interfaces.  These types would *not* have a parent type, though
+they would have progenitor interfaces, and hence a set of
+interface ancestors.
+
+ > ... We want to make
+> sure that the syntax clearly distinguishes an interface declaration like:
+>
+> 	type I is I1 and I2 and I3;
+
+That is not a legal interface declaration.  Interface
+declarations always need the word "interface":
+
+     type I is interface and I1 and I2 and I3;
+
+>
+> from a "normal type" declaration like:
+>
+> 	type T is new I1 and I2 and I3 with ...;
+>
+> When I look at the syntax above, it's not clear to me if you are declaring
+> bona fide types or mere interfaces.
+
+All interface type declarations have the word "interface,"
+so I don't see the possible confusion.  I think it would
+be worse to have the word "new" but have no parent type
+specified immediately thereafter.
+
+>
+> Oh, and I hate to mention this, but it's awfully late.  At this point the
+> only part of the core language that you should be changing is AI 416...
+
+The morning after is always a bit late...
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, February 17, 2005  6:07 PM
+
+> I guess I was somewhat attracted to the idea these were *not*
+> like type derivations, in that they aren't inheriting code or components
+> from anything.  They are simply "promising" to implement one or
+> more interfaces.  These types would *not* have a parent type, though
+> they would have progenitor interfaces, and hence a set of
+> interface ancestors.
+
+I had suggested something like this well back at the start. I was told I was
+confused. I do not look kindly on being told I was right all along, but we
+should invent some totally new syntax to handle this. I thought then that
+interface ancestors needed to be added to root tagged record declarations
+(like we eventually did for tasks and protected types). Something like:
+
+    type Rec is tagged limited record {I1 and}
+         Comp1 : ...
+    end record;
+
+If we're going to declare types with no parents, they ought to look like
+them. And I see no reason whatsoever to invent a new kind of type
+declaration (as Tucker did) to support that.
+
+But make no mistake about it -- if we even think about changing this syntax,
+we'll have to delay the completion of the Amendment by at least one meeting.
+And that would substantially increase the likelyhood of running out of money
+and effort. It had better be *important* in order to do that.
+
+(If we were to make this change, we would have to reread the entire AARM
+looking for places where a parent is assumed if there are any progenitors.
+That's going to be a huge job.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February 17, 2005  6:49 PM
+
+I believe task and protected types that implement interfaces
+already have this situation, for what it's worth.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, February 18, 2005  3:08 AM
+
+> > 	type I is I1 and I2 and I3;
+>
+> That is not a legal interface declaration.  Interface
+> declarations always need the word "interface":
+>
+>      type I is interface and I1 and I2 and I3;
+
+Yeah, I can never get the syntax right.  We changed it so many times...
+
+>     type T is not limited and Int1 and Int2 with ...
+>     type TT is task and Int1 and Int2 with private;
+>     type PT is protected and Int1 and Int2 with private;
+>
+> All interface type declarations have the word "interface,"
+> so I don't see the possible confusion.  I think it would
+> be worse to have the word "new" but have no parent type
+> specified immediately thereafter.
+
+From the perspective of syntax, it seems clear to me that it ought to
+mimic the syntax for full type declarations, with the task/protected
+definition replaced by the word private.  Thus:
+
+	task type TT is new Int1 and Int2 with private;
+	protected type PT is new Int1 and Int2 with private;
+
+Having two unrelated syntax for the partial view and the full view would
+just be too confusing.
+
+The situation is a bit less clear for the "not limited" case, but my
+preference would go to:
+
+	type T is not limited new Int1 and Int2 with private;
+
+Anyway, the syntax is, as usual, not the big problem here.  The impact on
+the overall (static) semantics of the language is daunting.  You'd have to
+define the semantics of "partial task-ish" and "partial protected-ish"
+views.  And you'd have to decide what to do with generics: it would seem
+reasonable to define new kinds of formal types corresponding to the
+partial views above, with appropriate matching rules, and a definition of
+what you can do with the formal type inside the generic.
+
+At first sight, this looks like an earth-shattering change to me.  But if
+you really feel strongly about it you can always try to put together an
+AI.  Maybe we'll discover that it's not so bad after all.  (I have my
+doubts.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, February 18, 2005  5:45 AM
+
+I'll write an AI, if I continue to have
+enthusiasm for this.  Note that we allow
+*adding* an interface_list to task, protected,
+and interface type definitions, without
+forcing the use of "new".  What I am proposing
+is to add the ability to include an interface_list
+in record definitions and private type definitions.
+
+Then any type that is non-array composite would
+allow an interface_list, including derived types
+of course.  And if Randy finds it familiar, I hope
+that isn't a bad thing.  Two big changes that occurred
+during the evolution of the interface feature were:
+
+   1) non-limited types could implement limited interfaces;
+   2) task and protected type declarations allow an
+      interface list.
+
+I'm not sure we went back after making these two
+changes and reconsidered the original tight connection
+between the derived type syntax and interface_list.
+We clearly want to allow interfaces as parents of
+derived types, so one can change an abstract non-interface
+type into an interface type with minimum disruption.
+However, one may similarly want to add interfaces
+to a record type or a private type, without taking
+on the other requirements of a derived type (i.e.
+a parent), and that seems to me what is missing.
+
+As far as two different syntaxes for partial view
+tasks/protected and full view tasks/protected, we
+already have that if you declare a derived type
+whose parent is a task, protected, or synchronized
+interface.  It seems odd that you can get a partial
+view task only if you name a task interface, but not
+if you want to be more explicit about it.
+
+Anyway, I'll dump all these arguments into a !discussion
+section if I find the energy to write up an AI.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, February 18, 2005  8:05 AM
+
+Well, I don't know what version of Chapter 9
+my evil twin was reading, but clearly "new"
+is there, as clear as day, in protected
+and task types that implement interfaces.
+That certainly weakens my argument about
+leaving out "new" for the others.
+
+This AI may not see the light of day...
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, February 18, 2005  10:36 AM
+
+Humm; OK by me, but it leaves the original problem unaddressed. That is,
+that deriving a non-limited type from a limited interface (which is likely
+to be the most common kind) is messy. You pretty much have to put a dummy
+non-limited interface around, which hardly is going to increase the clarity
+of programs.
+
+The problem seems limited (see below) to root record types, so that seems to
+be the only thing that needs addressing. Let's leave "new" in the syntax.
+Perhaps we need to add that to root record types:
+    type Rec is tagged new I1 and I2 record
+which would be a good thing if I1 and I2 were limited. The grammar would be:
+    record_type_definition ::=
+      [[abstract] tagged [new interface_list]] [limited] record_definition
+(The idea is that the interface list associates with "tagged", same as
+"abstract".)
+
+That would be pretty consistent with task and protected types (I dropped
+"with" here, because it doesn't make sense before "record", and this doesn't
+belong after "record").
+
+I'm not sure that this is a good idea, but if you are going to pursue
+something, I think it should be on this line.
+
+I have a lot harder time getting excited about partial views of task or
+protected types, because I think that the interface will naturally have one
+of the right classes in most interesting cases. Nonlimited isn't allowed,
+and all of the others seem fine to specify a partial view.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Saturday, February 19, 2005  7:48 AM
+
+I think you may have the same problem with non-limited private
+types/extensions, where you are required to make the limitedness
+of the partial view match the limitedness of the full view.
+Your idea of using "tagged" as a stand-in for "non-limited"
+is intriguing, though it is a bit subtle. Another possibility
+is to define non-terminals "parent_subtype_indication" and
+"ancestor_subtype_indication" used by derived_type_definition
+and private_type_extension as follows:
+
+    parent_subtype_indication ::=
+       subtype_indication | [not] limited
+
+    ancestor_subtype_indication :=
+       subtype_indication
+     | [not] limited | task | protected | synchronized
+
+and then say that when the parent_subtype_indication is given by
+a type "category" rather than a subtype_indication, the parent
+type is an anonymous operation-less interface type of the
+appropriate category.  This way we still have a parent type,
+albeit anonymous, which has exactly the desired characteristics.
+You would be allowed to have a "hidden" anonymous interface ancestor
+of course, since we have other rules that determine when limitness,
+nonlimitedness, etc., need to be revealed.
+
+I might be tempted to call these anonymous interfaces the "root"
+interfaces, but that might create some wording headaches
+(or heartaches? ;-).
+
+Here are examples of using this anonymous interface parent syntax.
+I presume we would not allow this notation in the absence
+of an interface_list (and that could probably be expressed
+in the BNF).
+
+    type NT is new not limited and Int1 with private;
+    type TT is new task and Int2 with private;
+    type NR is new not limited and Int3 with record ... end record;
+    type NNR is new not limited and Int4 with null record;
+
+Following Randy's suggestion, substituting "tagged" for
+"not limited" is a possible alternative, though I fear
+that might be confusing, albeit a bit pleasanter grammatically.
+
+> I have a lot harder time getting excited about partial views of task or
+> protected types, because I think that the interface will naturally have one
+> of the right classes in most interesting cases. Nonlimited isn't allowed,
+> and all of the others seem fine to specify a partial view.
+
+Yes, I agree this is less important, though I do suspect
+we will see the creation of operation-less task interfaces,
+which could create annoyances when integrating independently
+developed code.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, March 3, 2005  4:46 PM
+
+The more I think about this problem, the more it seems
+that adding syntax to solve this problem is overkill.
+Adding one additional library package with just a
+"bit" of magic would seem to solve the problem:
+
+    package Ada.Root_Interfaces is
+        type Root_Limited is limited interface;
+        type Root_Nonlimited is interface and Root_Limited;
+        type Root_Synchronized is
+          synchronized interface and Root_Limited;
+        type Root_Task is
+          task interface and Root_Synchronized;
+        type Root_Protected is
+          protected interface and Root_Synchronized;
+    end Ada.Root_Interfaces;
+
+
+All tagged types and interfaces implicitly
+implement Root_Limited.
+All non-limited tagged types and interfaces implicitly
+implement Root_Nonlimited.
+All synchronized tagged types and interfaces implicitly
+implement Root_Synchronized.
+All task interfaces implicitly implement Root_Task, as
+do all tagged task types (i.e. those that implement at least
+one interface).
+All protected interfaces implicitly implement Root_Protected,
+as do all tagged protected types (i.e. those that implement
+at least one interface).
+
+
+Then any time you want to define a non-limited type
+that also implements a limited interface:
+
+     type T is new Ada.Root_Interfaces.Root_Nonlimited and lim_intf
+       with ...
+
+A partial view of a tagged task type becomes:
+
+     type TT is new Ada.Root_Interfaces.Root_Task with private;
+
+I believe I suggested something similar to this in the past,
+but it was more of a "nice to have."  Now with the ability
+to have non-limited types implementing limited interfaces, and
+the general ability to have partial views of task types presuming
+they implement some interface, it seems important to have
+some way to specify an interface of a particular sort without
+having to create one just for the purpose.
+
+This seems preferable to new syntax...
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, March 4, 2005  3:13 AM
+
+You have indeed proposed exactly the same idea not so long ago.  See the
+mail dated October 26, 2004 in AI 345.  Surely no new technical
+information has surfaced since then.  In particular, it was already
+possible for non-limited types to implement limited interfaces.
+
+--
+
+I think that all the arguments that have been voiced at the time against
+this idea are still valid.  I will merely point out that this is a hybrid
+approach, and I find that particularly distasteful.  Long ago we decided
+to use syntax to declare interfaces; thus:
+
+	type TI is task interface;
+
+as opposed to using magic types, which would have looked like:
+
+	type TI is interface and Ada.Root_Interfaces.Root_Task;
+
+I believe that using syntax was the right approach, because it improves
+legibility and avoids the confusion that results from having a single root
+for the entire inheritance hierarchy.
+
+But now you are proposing to mix up the two approaches, so the two
+declarations below would be equivalent:
+
+	type I2 is interface and Ada.Root_Interfaces.Root_Task and I1;
+	type I2 is task interface and I1;
+
+This doesn't make sense to me.  There must be only one way to declare
+interface I2, not two ways based on whether you prefer syntax or magic
+interfaces.  So if we go for magic interfaces, we must get rid of the
+syntax for declaring limited/synchronized/task/protected interfaces.
+
+--
+
+One thing that I dislike with the rules as they currently are is that the
+order of the interfaces matters (and your proposal doesn't change that).
+Consider:
+
+	type LI is limited interface;
+	type NLI is interface;
+
+	type T1 is new LI and NLI with null record; -- limited
+	type T2 is new NLI and LI with null record; -- nonlimited
+
+The fact that T1 and T2 differ wrt limitedness is confusing and I wonder
+if we should try to change this.  Of course, in the case where the parent
+is a non-interface type, the limitedness has to be inherited from the
+parent.  But in the case where the parent is an interface type, I am not
+sure if the rule we have is ideal.  I might try to write an AI to fix
+this.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Satursday, March 5, 2005  5:00 PM
+
+Pascal Leroy wrote:
+
+>	type T1 is new LI and NLI with null record; -- limited
+>	type T2 is new NLI and LI with null record; -- nonlimited
+>
+>The fact that T1 and T2 differ wrt limitedness is confusing and I wonder
+>if we should try to change this.  Of course, in the case where the parent
+>is a non-interface type, the limitedness has to be inherited from the
+>parent.  But in the case where the parent is an interface type, I am not
+>sure if the rule we have is ideal.  I might try to write an AI to fix
+>this.
+
+I think it is extremely confusing, which is why I proposed that a type
+that inherits only from interfaces must contain the reserved word
+'limited' to be a limited type:
+
+	*type* T1 *is limited new* LI *and* NLI *with null record*; -- limited
+	*type* T2 *is new* LI *and* NLI *with null record*; -- nonlimited
+
+The only problem with this idea, and I am not sure it is a problem, is
+when such a type must be limited because one of the parent interfaces is
+synchronized or a task interface.  Favoring readers over writers in that
+situation argues for a legality rule.  Yes, the writer may be a bit
+exasperated as he goes back to add the (otherwise unnecessary)
+'limited.'  but readers would sure find it useful.
+
+This could be extended to allow/require:
+
+      *type* T2* is not limited **new *L1* and *NLI* with null record;
+*
+I my opinion that would be extreme overkill.  In Ada the rule is that a
+type is non-limited, unless it is derived from a limited type, is a task
+or protected type, or is defined to be limited.  Let's keep it that
+way.  Incidentally I am not at all sure that it is necessary that types
+that implement synchronized interfaces must be limited.  But I don't see
+any real reason to open that can of worms in the declaration.  Certainly
+there will be cases where in the body of the package that implements a
+synchronized type copying objects of the type may be necessary.  But in
+those cases I expect that the visible type will be a record containing
+an indirection pointer.*
+*
+****************************************************************
+
+From: Tucker Taft
+Sent: Saturday, March  5, 2005  7:30 AM
+
+Pascal Leroy wrote:
+
+> One thing that I dislike with the rules as they currently are is that the
+> order of the interfaces matters (and your proposal doesn't change that).
+> Consider:
+>
+> 	type LI is limited interface;
+> 	type NLI is interface;
+>
+> 	type T1 is new LI and NLI with null record; -- limited
+> 	type T2 is new NLI and LI with null record; -- nonlimited
+>
+> The fact that T1 and T2 differ wrt limitedness is confusing and I wonder
+> if we should try to change this.  Of course, in the case where the parent
+> is a non-interface type, the limitedness has to be inherited from the
+> parent.  But in the case where the parent is an interface type, I am not
+> sure if the rule we have is ideal.  I might try to write an AI to fix
+> this.
+
+Ok, I'm convinced.  Not to preempt you, but combining various
+suggestions from you, Randy, Robert Eachus, etc., I would
+support the following:
+
+     type NT is [abstract] [limited] new I1 and I2 and I3 with ...
+
+Limitness may be asserted on a derived type, in the
+same way it may be asserted on a record type.  Limitness
+is *not* inherited from a parent or progenitor that is a
+limited, non-synchronized interface, so limitness *must* be
+asserted if the parent and progenitors are all limited,
+non-synchronized interfaces, and the programmer wants
+the derived type to be limited.
+
+We could go further and say that limitness is *not*
+inherited from interfaces, period.  That would mean
+that "limited new" is *required* if the parent or any of
+the progenitors are synchronized.  I suppose that would
+be consistent with the current rule for tagged limited
+record types, where you have to say limited explicitly
+even if there is a task or protected component.  It
+would also be consistent with our rule on defining
+interfaces, where you must respecify limited (or some
+other qualifier like "synchronized") always,
+independent of the progenitors.
+
+I would allow limitedness to be asserted when it *is*
+inherited, so that you can change between an interface
+and a tagged type during maintenance, and not have to
+remove "limited" from the places where it is now
+inherited.  This would be consistent with untagged
+records, where we allow "limited" even when it is
+redundant.
+
+I suppose we could go further and allow "limited" to
+be asserted on an untagged derived type, and in that
+way support a coding convention where limited is always
+re-asserted, whether required or not, as documentation.
+Perhaps in Ada 2015, we could make it mandatory,
+in the same way "abstract" is always re-specified.
+Or even now, we could make omitting "limited" obsolescent.
+
+I suppose the one downside here is in a generic, where you
+*want* to inherit from the formal type without having
+to specify whether or not the derived type is limited.
+So it seems like we probably want to continue to allow
+"limited" to be implicit in some circumstances.
+This might actually argue for saying you don't inherit
+limitness from a null record type, to keep the equivalence
+between an interface and a null record type.  On the
+other hand, a null record type can easily become non-null
+during maintenance, whereas an interface will forever
+have no components.  But we do need to keep an eye on
+this equivalence between interfaces and null records,
+especially with respect to generics.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Saturday, March  5, 2005  9:47 AM
+
+Tuck wrote:
+
+> Ok, I'm convinced.  Not to preempt you, but combining various
+> suggestions from you, Randy, Robert Eachus, etc., I would
+> support the following:
+>
+>      type NT is [abstract] [limited] new I1 and I2 and I3 with ...
+>
+> Limitness may be asserted on a derived type, in the
+> same way it may be asserted on a record type.  Limitness
+> is *not* inherited from a parent or progenitor that is a
+> limited, non-synchronized interface, so limitness *must* be
+> asserted if the parent and progenitors are all limited,
+> non-synchronized interfaces, and the programmer wants
+> the derived type to be limited.
+
+Sounds OK.
+
+> We could go further and say that limitness is *not*
+> inherited from interfaces, period.  That would mean
+> that "limited new" is *required* if the parent or any of
+> the progenitors are synchronized.  I suppose that would
+> be consistent with the current rule for tagged limited
+> record types, where you have to say limited explicitly
+> even if there is a task or protected component.  It
+> would also be consistent with our rule on defining
+> interfaces, where you must respecify limited (or some
+> other qualifier like "synchronized") always,
+> independent of the progenitors.
+
+That sounds OK, too.  This rule might be easier for programmers to learn
+and remember, so I slightly prefer it.
+
+> I would allow limitedness to be asserted when it *is*
+> inherited, so that you can change between an interface
+> and a tagged type during maintenance, and not have to
+> remove "limited" from the places where it is now
+> inherited.  This would be consistent with untagged
+> records, where we allow "limited" even when it is
+> redundant.
+
+I don't like allowing it.  Anything that's not forbidden is required.
+;-)
+
+The analogy with "limited record" doesn't work.  The real rule (the one
+I follow in my code) is to always say "limited record" on a limited
+record.  I think we didn't make that the language rule purely for upward
+compatibility.
+
+But the corresponding rule "always specify limited on a limited derived
+type" seems like overkill.
+
+The changing-to-interface argument is a good one.  But it doesn't seem
+like that big of a deal -- you're changing the code anyway, and
+recompiling it all, so it's not so horrible to go around and add
+"limited" all over.
+
+> I suppose we could go further and allow "limited" to
+> be asserted on an untagged derived type, and in that
+> way support a coding convention where limited is always
+> re-asserted, whether required or not, as documentation.
+> Perhaps in Ada 2015, we could make it mandatory,
+> in the same way "abstract" is always re-specified.
+> Or even now, we could make omitting "limited" obsolescent.
+
+I could live with the option suggested as an *option*,
+but I'd be against making it mandatory in 2015 (or ever).
+
+Limitedness is unlike abstractness.  Abstractness is a property of a
+specific type, and it makes no sense to inherit it.  Limitedness is a
+class property, and should be inherited from the parent type, just like
+all the other operations.  (Pascal is wrong to think that having a named
+type for the root of this hierarchy is a kludge.  Trees are cleaner than
+forests; all hierarchies should have roots.  But he's right that the
+mixed-syntax-and-magic-types idea was kind of ugly.)  Anyway, it would
+not be upward compatible.
+
+Making this an option makes sense only if you think people should always
+do it, and compatibility prevents you from making it a real rule.  But I
+don't think that, so I wouldn't follow such a convention.  Options like
+this cause the language to diverge into different styles.  There are at
+least three different styles floating around for whether to put 'in' on
+an in-mode parameter, and that's not helpful; Ada 83 should have made it
+mandatory or forbidden.
+
+> I suppose the one downside here is in a generic, where you
+> *want* to inherit from the formal type without having
+> to specify whether or not the derived type is limited.
+
+I took advantage of that in some code I wrote recently.
+
+> So it seems like we probably want to continue to allow
+> "limited" to be implicit in some circumstances.
+> This might actually argue for saying you don't inherit
+> limitness from a null record type, to keep the equivalence
+> between an interface and a null record type.
+
+That wouldn't be upward compatible.  In the case I mentioned above, the
+thing I was inheriting from *was* a null record (sometimes limited,
+sometimes not).
+
+>...On the
+> other hand, a null record type can easily become non-null
+> during maintenance, whereas an interface will forever
+> have no components.  But we do need to keep an eye on
+> this equivalence between interfaces and null records,
+> especially with respect to generics.
+
+How so?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Saturday, March  5, 2005  12:30 PM
+
+>>We could go further and say that limitness is *not*
+>>inherited from interfaces, period. ...
+>
+>
+> That sounds OK, too.  This rule might be easier for programmers to learn
+> and remember, so I slightly prefer it.
+
+Yes, it seems simpler to say that limitness is
+not inherited from an interface, even if it is synchronized.
+That applies whether the new type is an interface
+or is a "normal" tagged type.
+
+ >> ...  But we do need to keep an eye on
+>>this equivalence between interfaces and null records,
+>>especially with respect to generics.
+>
+>
+> How so?
+
+An interface can be passed as an actual type when the formal
+is an abstract limited tagged type.  If you extend this
+formal type inside the generic, then whether you inherit
+limitness from it depends on whether or not the actual
+turns out to be an interface (based on this new proposal).
+That breaks the equivalence between interfaces and
+abstract null records, which is OK, since we know
+that interfaces have some special properties, but we
+have to be sure that this distinction doesn't break
+some other assumption.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Saturday, March  5, 2005  6:19 PM
+
+My head hurts a lot after just reading this, and I am not sure I see
+the advantage to what could be a maintenance nightmare for both Ada
+programmers and compiler implementors.  I can see reasons for passing an
+interface to a generic as an interface, and probably there is an
+advantage to providing a generic formal type that matches all the
+possibilities:
+
+type Formal is new {limited | task | protected | synchronized} interface;
+
+(Currently AI-345 seems to match this, except for the limited.)
+
+I don't quite understand, though, why a generic formal synchronized
+interface can't be matched by a protected interface. And I can't seem to
+get my mind around Tuck's comment above and AI-251.  I had been thinking
+of interface types as a class hierarchy where an interface of lesser
+generality could be passed as an actual.  In other words, a generic that
+took a synchronized interface as a formal parameter could have an actual
+which was a task or protected interface.  Of course the interface type
+must be derived from within the generic to do anything useful with it,
+and there the hierarchy does come into play.  But AI-251 seems to assume
+that there is no easy way to have the actual interface type do other
+than match the formal.  I don't see the implementation difficulties--but
+I also don't see any reason not to have that restriction.  The case that
+Tuck is in effect arguing for looks much more difficult than
+synchronized formal and protected actual interfaces, and much less
+useful.  Am I missing something?
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Monday, March  7, 2005  9:59 AM
+
+> I would
+> support the following:
+>
+>      type NT is [abstract] [limited] new I1 and I2 and I3 with ...
+
+Fine.
+
+> We could go further and say that limitness is *not*
+> inherited from interfaces, period.  That would mean
+> that "limited new" is *required* if the parent or any of
+> the progenitors are synchronized.
+
+That's what I prefer.  It's easier to explain.  And limitedness of
+interfaces is peculiar anyway, since a limited interface can be
+implemented by a limited type.  (Interfaces are analogous to generic
+formal types from that perspective: the fact that a formal is limited
+doesn't guarantee that an actual is; the fact that an interface is limited
+doesn't guarantee that a concrete type is.)
+
+I have been playing for some time with the notion that *nonlimitedness*
+should be inherited for interfaces: if an interface is nonlimited, it
+depends on the fact that any concrete type has assignment and "=".  But of
+course inheriting nonlimitedness is at odds with the rest of the language.
+Your approach is better.
+
+> I would allow limitedness to be asserted when it *is* inherited
+
+Like Bob, I don't like optional syntax.
+
+> I suppose we could go further and allow "limited" to
+> be asserted on an untagged derived type, and in that
+> way support a coding convention where limited is always
+> re-asserted, whether required or not, as documentation.
+> Perhaps in Ada 2015, we could make it mandatory, in the same
+> way "abstract" is always re-specified. Or even now, we could
+> make omitting "limited" obsolescent.
+
+Nay, don't go there, too late, and not useful enough.  Jean should have
+done it that way back in '79.  Let's blame him, as usual.
+
+> This might
+> actually argue for saying you don't inherit limitness from a
+> null record type, to keep the equivalence between an
+> interface and a null record type.  On the other hand, a null
+> record type can easily become non-null during maintenance,
+> whereas an interface will forever have no components.  But we
+> do need to keep an eye on this equivalence between interfaces
+> and null records, especially with respect to generics.
+
+If we can preserve this equivalence between interfaces and abstract null
+records, fine, but I wouldn't bend over backwards to do it.  First, I
+don't think there are many abstract null records out there: when I use
+abstract types, I always put "common" components there; if there are no
+common components, sure, I have a null record, but it's a fluke rather
+than a conscious decision.  Second, I believe that taking advantage of
+interfaces will require serious rearchitecturing, so people won't do that
+as an afternoon project by peppering a few packages with the word
+"interface".  Chances are that massive changes will be required anyway.I
+am wondering now if the fact that an interface can be passed to an
+abstract formal type is creating a hole.  Consider:
+
+	type Intf is interface;
+
+	generic
+	   type A is abstract tagged private;
+	package G is
+	   type T is tagged private;
+	private
+	   type T is new A with ...
+	end G;
+
+	package Inst is new G (Intf);
+
+It seems that the instantiation Inst is effectively violating the
+no-hidden-interfaces rule.  Am I missing something, or should this just be
+illegal?
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Monday, March  7, 2005  10:07 AM
+
+> Pascal is wrong to think that having a named type for the
+> root of this hierarchy is a kludge.  Trees are cleaner than
+> forests; all hierarchies should have roots.
+
+You won't convince me and I won't convince me, but hopefully you'll agree
+that changing Ada from a forest language to a tree language is a major
+design decision, and should not happen as part of a last-minute fix.
+
+Not to mention that you were part of the 9X design which, in its infinite
+wisdom, chose to make Ada a forest language ;-)
+
+(Actually, Ada is tree-ish in the sense that all "interesting" types have
+to be derived from Ada.Finalization.Controlled.  After 10 years of usage,
+it still sticks out like a sore thumb.)
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Monday, March  7, 2005  10:18 AM
+
+> I don't quite understand, though, why a generic formal synchronized
+> interface can't be matched by a protected interface.
+
+This has been puzzling me for a long time, too, but one rather compelling
+answer is that there are things that you can do with synchronized
+interfaces and that you cannot do with protected interfaces.  In
+particular, you can extend a protected interface to create a taskish
+thing.  Consider:
+
+	generic
+	   type SI is synchronized interface;
+	package G is
+	   type TI is task interface and SI;
+	   task type TT is new SI with
+	      entry E;
+	   end TT;
+	end G;
+
+If G could be instantiated with a protected interface, it would be bad
+news, because TI would be a task-and-protected interface, and TT would be
+a task-and-protected type.
+
+This could be taken care of by rechecking the rules on instantiation, and
+assuming-the-worst in generic bodies.  But that doesn't seem like the
+right trade-off.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, March  7, 2005  12:50 PM
+
+> That's what I prefer.  It's easier to explain.  And limitedness of
+> interfaces is peculiar anyway, since a limited interface can be
+> implemented by a limited type.
+
+I bet you meant "by a *non*limited type."
+
+
+
+>>I would allow limitedness to be asserted when it *is*
+>>inherited
+>
+>
+> Like Bob, I don't like optional syntax.
+
+But I think you want to at least allow it in a generic, since
+you may not know whether the parent is an interface or
+a "normal" abstract tagged type.  And if you want the
+new type to be limited even if the actual is an interface,
+there is no easy way to get that with this new rule.
+
+> ...I
+> am wondering now if the fact that an interface can be passed to an
+> abstract formal type is creating a hole.  Consider:
+>
+> 	type Intf is interface;
+>
+> 	generic
+> 	   type A is abstract tagged private;
+> 	package G is
+> 	   type T is tagged private;
+> 	private
+> 	   type T is new A with ...
+> 	end G;
+>
+> 	package Inst is new G (Intf);
+>
+> It seems that the instantiation Inst is effectively violating the
+> no-hidden-interfaces rule.  Am I missing something, or should this just be
+> illegal?
+
+I think the no-hidden-interfaces rule has to be applied in the private
+part of an instance.  Since you can't extend a formal tagged type
+in a body, then checking for no hidden interfaces can always be
+performed without breaking the contract model.
+
+I do think it is important to allow interfaces to be passed
+when the formal is an abstract tagged type, or else we will
+get into having to have two generics when one does the job.
+But we now have two differences between an interface and a
+"normal" abstract tagged type:
+
+   1) no hidden interfaces
+   2) limitedness not inherited
+
+These differences obviously complicate the model, but we pretty
+clearly can't impose the interface rules on all abstract types
+for compatibility reasons.  Imposing the equivalence only on abstract
+null records doesn't really help, because that just moves the "bump"
+to a new place, since you can't specify "nullness" of a generic
+formal abstract tagged type.
+
+So to summarize my suggestion:
+   1) You never inherit limitness from an interface;
+   2) You can always assert limitness on a type extension,
+      to address the possibility that the parent is a formal
+      abstract tagged type whose actual is a limited interface.
+
+Part (1) above jibes with the preference expressed by you and Bob.
+Part (2) above, which violates the "optional syntax" is bad metarule,
+I claim is analogous to the optional "limited" for record types
+with limited components -- think of a non-interface parent like
+a component, and you get pretty much the same model.  Predefined
+equality also treats a non-interface parent like a component,
+so there is some precedent there...
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March  7, 2005  1:45 PM
+
+> It seems that the instantiation Inst is effectively violating the
+> no-hidden-interfaces rule.  Am I missing something, or should this just be
+> illegal?
+
+It *is* illegal, because you always recheck legality rules in the spec. of
+an instance. Certainly this one doesn't pass that recheck. In the body, we
+don't allow deriving from a formal type anyway, for the precise reason that
+we can't recheck the legality rules, and there are a number of (existing)
+ones that can fail. This is just one more to add to that list. (The legality
+rule certainly apply in the private part of an instance; I've never
+understood why that isn't the default, *not* checking legality rules should
+be the unusual special case.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, March  7, 2005  2:30 PM
+
+I think we were trying to preserve the "fiction" that privacy
+applies when instantiating a generic.  But alas, in many cases,
+you need to look in the private part of the generic to know
+whether a given instantiation will be legal.
+
+I guess the real "privacy" rule that applies to generics is that
+to *use* an instance of a generic, you don't need to look in the
+private part.  But to instantiate a generic, you probably do need
+to look to see how the formal types are actually used in the
+private part.  I guess that shouldn't be *too* surprising...
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, March  7, 2005  3:12 PM
+
+Pascal wrote:
+
+> You won't convince me and I won't convince me, ...
+
+And *I* won't convince *me*.  ;-)
+
+>... but hopefully you'll agree
+> that changing Ada from a forest language to a tree language is a major
+> design decision, and should not happen as part of a last-minute fix.
+
+Yes, I agree.
+
+> Not to mention that you were part of the 9X design which, in its infinite
+> wisdom, chose to make Ada a forest language ;-)
+
+Hmm.  I don't remember whether we proposed all of the Root_Limited and
+friends, but I do remember that we proposed a Root_Task type, and got
+tarred and feathered for it.  To this day, I think that was a cleaner
+solution than the Task_Ids package, which is untypesafe and allows
+dangling pointers.
+
+But I'm not pushing to add Root_Task *now*.
+
+> (Actually, Ada is tree-ish in the sense that all "interesting" types have
+> to be derived from Ada.Finalization.Controlled.  After 10 years of usage,
+> it still sticks out like a sore thumb.)
+
+Well, I still use untagged records quite a bit.  There are many places
+in my code where the overhead of finalization (given most compiler's
+implementations) would be intolerable.  I also use 'limited' quite a
+lot, because ":=" doesn't work, and I don't want Controlled.
+
+You may have noticed me pushing for various AI's that make limited types
+usable.  ;-)
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, March  7, 2005  5:21 PM
+
+> But I think you want to at least allow it in a generic,
+
+OK, I'm convinced.  I don't entirely buy your limited-records analogy,
+but the above generics argument is pretty compelling.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, March  8, 2005  5:17 AM
+
+> > Like Bob, I don't like optional syntax.
+>
+> But I think you want to at least allow it in a generic, since
+> you may not know whether the parent is an interface or a
+> "normal" abstract tagged type.  And if you want the new type
+> to be limited even if the actual is an interface, there is no
+> easy way to get that with this new rule.
+
+You're right.  But if you allow it in a generic, you have to allow it
+everywhere, because you want to make it easy to turn a nongeneric package
+into a generic (or vice-versa).
+
+> I do think it is important to allow interfaces to be passed
+> when the formal is an abstract tagged type, or else we will
+> get into having to have two generics when one does the job.
+
+I am not sure if I agree with this.  If it comes for free, fine, but if it
+hairs up the language, it bothers me.  I guess I don't see the need as
+compelling enough.  On the other hand if you cannot pass an interface to a
+generic formal abstract, it means that you don't have a "most general
+formal tagged type" and that's unpleasant.
+
+> But we now have two differences between an interface and a
+> "normal" abstract tagged type:
+>
+>    1) no hidden interfaces
+>    2) limitedness not inherited
+>
+> These differences obviously complicate the model, but we
+> pretty clearly can't impose the interface rules on all
+> abstract types for compatibility reasons.  Imposing the
+> equivalence only on abstract null records doesn't really
+> help, because that just moves the "bump" to a new place,
+> since you can't specify "nullness" of a generic formal
+> abstract tagged type.
+>
+> So to summarize my suggestion:
+>    1) You never inherit limitness from an interface;
+>    2) You can always assert limitness on a type extension,
+>       to address the possibility that the parent is a formal
+>       abstract tagged type whose actual is a limited interface.
+
+I strongly suggest writing an AI.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, March  8, 2005  8:02 AM
+
+I thought you were going to write one.  Did I preempt
+you with my blabbing so that now it is mine?  Let me
+know...
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, March  8, 2005  11:02 AM
+
+I guess you touched it last, so yes, it's yours.
+
+****************************************************************
+

Questions? Ask the ACAA Technical Agent