CVS difference for ais/ai-00401.txt

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

--- ais/ai-00401.txt	2005/06/16 23:47:40	1.6
+++ ais/ai-00401.txt	2005/10/31 05:18:41	1.7
@@ -1,4 +1,4 @@
-!standard 3.4(01)                                      05-05-05  AI95-00401/04
+!standard 3.4(01)                                      05-10-27  AI95-00401/05
 !standard 3.4(03)
 !standard 3.4(05)
 !standard 3.4(08)
@@ -159,7 +159,7 @@
 
 Change the paragraph added after 3.4(35) by AI95-00251 to read:
 
-An interface type which has a {progenitor type} "is derived from" that type.
+An interface type {that} has a {progenitor type} "is derived from" that type.
 A derived_type_definition, however, never defines an interface type.
 
 
@@ -388,7 +388,7 @@
 @xindent<@s9<17  If the reserved word @b<abstract> is given in the declaration
 of a type, the type is abstract (see 3.9.3).>>
 @dinst
-@xindent<@s9<18  An interface type which has a progenitor type "is derived
+@xindent<@s9<18  An interface type that has a progenitor type "is derived
 from" that type. A @fa<derived_type_definition>, however, never defines an
 interface type.>>
 
@@ -683,6 +683,1351 @@
 add interfaces without extension.
 
 So we can ignore the rest of your explanation. Thank goodness. :-)
+
+****************************************************************
+
+From: Erhard Ploedereder
+Sent: Monday, May 2, 2005  8:38 PM
+
+At the Paris meeting, I took an action item to check for overall consistency
+of parent vs. ancestor vs. progenitor, etc etc, i.e., the whole terminology
+that surrounds inheritance. Here is the outcome in sequence of the manual
+D-11, not necessarily importance, although the first ones are pretty
+significant; Pascal may rule one or the other out of bounds.
+
+Erhard
+
+-------------------------
+
+Comments on Interface Semantics:
+-------------------------------
+
+I was unable to find a rule that allowed abstract subprograms inherited from
+interfaces to be implemented by subprograms inherited from the parent. Such
+a rule is essential and certainly is not derivable -quite the contrary- from
+current abstract subprogram rules. Presently, it seems that all the
+subprograms inherited from interfaces need to be explicitly implemented in a
+concrete descendant type (since they are treated as inherited abstract
+subprograms which must be overridden). THIS CANNOT POSSIBLY BE THE
+INTENT OF INTERFACES.
+
+Note in particular the interesting situation where a concrete parent type
+implements Interface I and the derived type implements NI, a descendant of
+I.  Here it is unavoidable that an implementation from a parent meets a spec
+from a progenitor. This must be legal and there mustn't be a need to
+override again what is already implemented for the parent.
+
+The very thought that the accumulated load of subprogs of a specialized
+interface needs to be explicitly wrapered again, merely because I wanted to
+add the 3 very special routines there to my class hierarchy, is daunting.
+
+-----------------
+
+I did not find a rule that explained what happens when "almost
+identical" subprogs are inherited from multiple interfaces, i.e., is
+it o.k. to multiply inherit the same or mode- or subtype- or
+type-conformant signatures?  (While this question was a bit
+pathological in the context of homographs created by generic
+instantiations where I believe calls become ambiguous, here it will be
+commonplace and there better be an answer that allows them without any
+problems, signature of the overriding winning in case of differences)
+
+-----------------
+
+I did not find a rule that allowed multiple subtype-conformant specs
+inherited from multiple progenitors to be implemented by a single
+overriding declaration. (Maybe none is needed; the words for the
+"implemented-by" synchronized interfaces seem to work for multiple specs.
+The words for abstract subprograms are not so resistant to doubt. )
+
+--------------------
+
+3.9.2 (20) dispatches only to overriding bodies, not to "implemented
+by" bodies.  So dispatching doesn't work for implemented-by ops of
+synchronized interfaces.  Fix 3.9.2(20) to include both kinds.
+
+... or ...
+
+Ceterum Censeo and hence you can ignore: to use the
+overriding_indicator "overriding" for "implemented-by" bodies and, at
+the same time, make a semantic rule that "implemented-by" is not
+"overriding", is atrocious language design.  PLEASE; PLEASE, UNDO
+THIS STUPID DISTINCTION BETWEEN OVERRIDING AND IMPLEMENTED-BY. It'll
+bite again and again. Make it a principle that one dispatches (only) to
+overriding subprogs (if and only if!)
+
+---------------------------
+
+3.4 (1.a); N (13):  Glossary...is a bit wrong now.
+
+3.4 Rule is missing that interface lists allow only interface types !!!!
+  (was found in 3.9.*; will be solved per decision at Paris mtg)
+
+3.4 (5) should say "record_extension_part or an interface_list"  (and-> or;
+  no parenthesis; Reason: simple logic)
+
+3.4(15/2) "appears" (where?) -> "is present in the derived_type_definition."
+
+-----
+3.4 (16) are there no predefined ops for interface types ?
+    '(17/2) for equality, the rules are wrong!!!
+        consider: parent is limited interface; some progenitor has a
+              user-defined "=" (but is limited);
+              does the resulting type inherit "=" ?
+              The rules say "no", they should say "yes", because the
+              progenitor has equality (and the type better not be
+              without the "="!!!)
+              Does it matter beyond the limited type case? Probably not,
+              because the new type has its own predefined equality, which
+              now implements the "="; unless...
+    (17/2) if there are other predefined primitive ops for interfaces, they
+           need to be dealt with here. Are there?
+-----
+
+3.4 (21) what if the parent type is an interface type, as is allowed ?
+Then the sentence makes no sense, since the parent (sub)type should be
+seen as infinite, should it not?
+If the sentence should apply to interface parents, the principle should
+apply to the interfaces inherited from progenitors as well in the context of
+the co-variant inheritance. Admittedly, it seems to be trivially true today,
+since interfaces don't have discriminants; but I am bothered by "shortening"
+the rule just because this is how it is in today's definition.  The
+"convertability" ought to be to all ancestors.
+
+------
+
+3.9 terminology: interface vs interface type ... note that normally the
+  prefix term is reserved for the objects of the type. E.g., the task X of
+  task type T.
+  Here "interface" is sometimes used to mean interface type.
+  1.b.2/2; 12.a/2, 3.9.1 4.m/2, ....
+  Should be fixed.
+The fact that the abbreviation is in fact defined (in 3.9.4 (3/2)), makes it
+legit, but still not helpful, just lazy.
+  X: I;  -- the interface X of interface I ??????
+
+-------
+
+3.9.(1k) 2.line "parent" -> "parent or progenitor"; the rule applies
+to the inherited subprograms originating from normal progenitors as
+well.
+Anything to be stated about synchronized progenitors?
+
+----------
+
+3.9. 2/2   typo: ...interface type is [a] tagged type.
+
+--------
+
+3.9.1 3/2 2.sentence : parent -> the parent or a progenitor type !!
+          (the sentence definitely applies to both)
+          (Remember: it is possible that the parent type is an interface,
+           so it is legit to have a limited parent, but a non-limited type
+           here.)
+
+---------
+
+3.9.2(10/1) <<<most comments obsolete due to discussion at Paris
+meeting and lawyerly distinction made between implemented by and
+overriding for synchronized types. note: if the distinction goes away,
+convention rules are needed here.>>>
+
+However there is one case remaining: inheriting a null procedure from
+a progenitor or redefining it: what is the Convention? So far,
+3.9.2(10/1) only talks about inheriting from parent types.
+
+---------
+
+3.9.3 (4/2) I could not parse the sentence in less than 3 minutes (and
+still am unsure of what it tries to say); an earlier comment said that
+I could not parse it at all. 3 minutes helped. Still unsure what the
+"or a type other than..." binds to (the type, the parent or the
+ancestor type or none of the above).  Now I need 30 minutes of
+semantic analysis. :-)
+
+---------
+
+The argument in 4.5.2 (14.b/2) seems wrong: formal derived types can also
+have parent types. Are they full types?
+
+--------
+
+4.6 23.b  "parent -> ancestor" !
+          because conversions also from progenitors (in fact ancestors in
+          general)
+
+---------
+
+7.3.(20) : "definitely to be extended to the progenitors !" is my original
+          note. 20.1/2 does that. What remains is some worry that the words
+          in 20 may be wrong in case the parent is an interface type.
+
+---------
+
+7.5 (2/2) : no brackets please (where is it derivable from?)
+
+---------
+7.6 Could Controlled become interface now ????
+    I know that this is "far out", but it would do away with the bloody
+    nuisance that Controlledness cannot be mixed-in today. (It would
+    require "magic" by the compiler, since it presumably involves data.
+    Just a thought and yes, shoot the engineer.)
+----------
+
+9.1  (9.2/2) typo: profile of [the] inherited subprog
+
+------
+
+9.1  (9.d/2)
+   what is a name interface? how does the first part of the sentence parse?
+   missing "a" in "Only [a] limited"
+
+   same comments for 9.4 11.d/2
+
+
+-------
+12.5.1 (5.1/2) actual must descend all progenitors, but NOT the parent ???
+               (while later rules deal with the parent, it is really bad
+                description to not include the parent here)
+
+------
+
+12.5.1. (21/2) typo "progentor";  typo missing blank in "ancestoror"
+        The content is bogus; apparently the "and progenitor" in the
+        first sentence was added in the wrong place. Should be added
+        after "by the ancestor type" and should say "and any
+        progenitor types"
+        there is a displaced blank later "  or progenitoris"
+
+12.5.1. (21.a/2) typo "progentor" and double blank before it
+---------
+
+
+A (musing) observation:
+
+Interface Interf;
+procedure foo(X: Interf) is null;
+procedure bar(X: Interf);
+
+seems that just about the only place in the code where I can mutter
+"Interf" is in an interface_list. Everywhere else, it's Interf'Class to
+be usable at all, since I cannot have objects of type Interf.
+Correct?
+If not so, enlighten me. But then, it'll come as a bloody surprise that
+procedure test(X: Interf) is
+begin
+     bar(X); -- dispatching call, of course
+     foo(X); -- does not dispatch; does nothing
+end test;
+I wanted a "null" at the bottom of a dispatching wrapper hierarchy, but this
+defeats the very idea and makes the call non-dispatching.
+
+----------------
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, May 2, 2005  10:24 PM
+
+> I did not find a rule that explained what happens when "almost
+> identical" subprogs are inherited from multiple interfaces, i.e., is
+> it o.k. to multiply inherit the same or mode- or subtype- or
+> type-conformant signatures?  (While this question was a bit
+> pathological in the context of homographs created by generic
+> instantiations where I believe calls become ambiguous, here it will be
+> commonplace and there better be an answer that allows them without any
+> problems, signature of the overriding winning in case of differences)
+
+That's the purpose of 8.3(12.1-12.3 and 26.1-26.2). I suggest reading these
+rules carefully to see if they cover this and other questions that you raise
+here, and (if your head doesn't explode first ;-), report your findings. (I
+believe that they do, but I have to save my head for the AARM and all of the
+other editorial comments.)
+
+>
+> -----------------
+>
+> I did not find a rule that allowed multiple subtype-conformant specs
+> inherited from multiple progenitors to be implemented by a single
+> overriding declaration. (Maybe none is needed; the words for the
+> "implemented-by" synchronized interfaces seem to work for multiple specs.
+> The words for abstract subprograms are not so resistant to doubt. )
+
+See above. It seems that you missed 8.3 altogether.
+
+> --------------------
+>
+> 3.9.2 (20) dispatches only to overriding bodies, not to "implemented
+> by" bodies.  So dispatching doesn't work for implemented-by ops of
+> synchronized interfaces.  Fix 3.9.2(20) to include both kinds.
+
+This looks like a hole.
+
+> ... or ...
+>
+> Ceterum Censeo and hence you can ignore: to use the
+> overriding_indicator "overriding" for "implemented-by" bodies and, at
+> the same time, make a semantic rule that "implemented-by" is not
+> "overriding", is atrocious language design.  PLEASE; PLEASE, UNDO
+> THIS STUPID DISTINCTION BETWEEN OVERRIDING AND IMPLEMENTED-BY. It'll
+> bite again and again. Make it a principle that one dispatches (only) to
+> overriding subprogs (if and only if!)
+
+I can't ignore it, I don't know Latin. (A US public school education. :-)
+
+I think this is a damned if you do, damned if you don't situation. The
+differences between "overriding" and "implemented by" are significant enough
+that we *have* to have some terminological difference between them. I suppose
+we could stick some sort of adjective on "overriding", say "normal overriding"
+and "prefixed overriding", and then try to make all of the rules work. But if
+we do that, I hope Ada Europe has some more money to spend on this, because it
+would take a lot of work to carefully check everything  several more times.
+
+I'll leave someone else to look over the rest of it. (Or do it some other time;
+say September.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, May 2, 2005  11:29 PM
+
+> 3.9.2 (20) dispatches only to overriding bodies, not to "implemented
+> by" bodies.  So dispatching doesn't work for implemented-by ops of
+> synchronized interfaces.  Fix 3.9.2(20) to include both kinds.
+
+Good point.  We should include bodies that are implemented by
+protected operations or task entries as legitimate, albeit
+compiler-generated, bodies.
+
+>
+> .. or ....
+>
+> Ceterum Censeo and hence you can ignore: to use the
+> overriding_indicator "overriding" for "implemented-by" bodies and, at
+> the same time, make a semantic rule that "implemented-by" is not
+> "overriding", is atrocious language design.  PLEASE; PLEASE, UNDO
+> THIS STUPID DISTINCTION BETWEEN OVERRIDING AND IMPLEMENTED-BY. It'll
+> bite again and again. Make it a principle that one dispatches (only) to
+> overriding subprogs (if and only if!)
+
+I understand your concern, but as Randy points out, the distinction
+is quite important.  The notion of a compiler-provided "wrapper" is
+pretty fundamental for the semantics to make sense here.  For example,
+the formal parameter names and the defaults come from the inherited
+subprogram, not from the protected/task op, when you call this
+operation in non-prefix notation.  That pretty much has to be true
+since the protected/task op doesn't even have a formal parameter
+name for the first parameter.
+
+It is unfortunate that the overriding indicator mucks up the
+terminology situation even further.  Perhaps Randy's idea of
+calling it "prefixed overriding" could help, though I think
+he is right that we could run into more confusion that way
+(analogous to the old confusion that a "generic package" is
+*not* a package).
+
+On the issue of interface semantics in general,
+as Randy pointed out, you seem to have missed
+8.3 completely, and that is where all the tricky rules
+are that relate to inheritance and overriding between
+multiple interface ancestors.  It sounds like we should
+have some sort of "pointer" to 8.3 from 3.9.4 (or 3.4), and/or
+summarize the rules in 3.9.4 (or 3.4) in AARM redundancy brackets.
+
+****************************************************************
+
+From: Erhard Ploedereder
+Sent: Tuesday, May  3, 2005  6:28 AM
+
+> I understand your concern, but as Randy points out, the distinction
+> (of "overriding" and "implemented-by") is quite important.
+
+No argument given. Of course it is important...however, distinction does not
+necessarily imply exclusion. For example, call it "protected overriding" or
+"synchronized overriding" (and all overriding rules apply, except for the
+ones that "implemented by" presently modifies; the only other place to
+also modify is the identified one on Convention).
+
+Actually, give me an answer to comment Uno first, which does have a bearing
+on the problem: are we serious that ops inherited from an interface cannot
+be implemented by the parent?  If this is so, the interface capability is
+about as useful as Ada95 OOP was a few months prior to its release, when it
+didn't work at all for objects designated by access values.  If this is not
+so, one needs to deal with interface ops implemented by inherited protected
+ops anyway, which equally require "implemented-by" rules.
+
+(I'll react to the 8.3 pointer separately.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, May  3, 2005  7:53 AM
+
+> ...
+> Actually, give me an answer to comment Uno first, which does have a bearing
+> on the problem: are we serious that ops inherited from an interface cannot
+> be implemented by the parent?
+
+This sentence sounds like the famous "when did you stop
+beating your wife?" question.  The answer is that a non-abstract
+operation inherited from one ancestor can override
+an abstract operation inherited from another.
+
+This is based on 8.3(12.1/2...):
+
+   If two or more homographs are implicitly declared at the same place:
+
+     * If one is a non-null non-abstract subprogram, then it overrides
+       all [which] {that} are null or abstract subprograms.
+
+     * If all are null procedures or abstract subprograms, then any null
+       procedure overrides all abstract subprograms; if more than one
+       homograph remains that is not thus overridden, then one is chosen
+       arbitrarily to override the others.
+
+There are some legality rules in 8.3(26.1/2) which guarantee when
+one is chosen arbitrarily, the choice doesn't matter, because they
+all must conform fully in that case.  But the rule you care about
+is the first one, namely a non-null, non-abstract inherited
+subprogram overrides all the null or abstract ones.  That gives
+you the effect you (and we all) want.
+
+
+ > ...
+  If this is so, the interface capability is
+> about as useful as Ada95 OOP was a few months prior to its release, when it
+> didn't work at all for objects designated by access values.  If this is not
+> so, one needs to deal with interface ops implemented by inherited protected
+> ops anyway, which equally require "implemented-by" rules.
+
+I don't see the connection.  The "implemented-by" rules
+for protected/task operations rely on a "wrapper" model,
+somewhat analogous to the way renaming-as-body is
+described.  The rules given in 8.3 are about one
+inherited operation overriding another.
+
+The wording in 3.9.2(20), which doesn't seem to work very
+well for the "implemented-by" case, does seem to handle
+adequately this case of one inherited operation overriding
+another (surprisingly).
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Monday, May  9, 2005 10:29 AM
+
+> 3.9.2 (20) dispatches only to overriding bodies, not to
+> "implemented by" bodies.  So dispatching doesn't work for
+> implemented-by ops of synchronized interfaces.  Fix 3.9.2(20)
+> to include both kinds.
+
+Yep, that's a bug.
+
+> PLEASE; PLEASE, UNDO THIS STUPID DISTINCTION BETWEEN
+> OVERRIDING AND IMPLEMENTED-BY. It'll bite again and again.
+> Make it a principle that one dispatches (only) to overriding
+> subprogs (if and only if!)
+
+Let's not go there.  As others have indicated, the difference is very
+significant from the language design standpoint.  Hopefully users should
+be able to ignore it most of the time, which is why I think that
+overriding_indicator is fine.
+
+Maybe this could have been better described by a 2-step mechanism: (1) the
+inherited operation is *overridden* by an implicit, subtype conformant
+subprogram and (2) this implicit subprogram is *implemented by* calling
+the entry or protected operation with the appropriate parameter mucking
+(and possibly different defaults, convention, etc.).  This would have made
+the wrapper model explicit, and dispatching would have worked "naturally".
+However it is too late to revise the wording in this direction, and this
+is insufficiently broken anyway.
+
+> 3.4 (5) should say "record_extension_part or an
+> interface_list"  (and-> or;
+>   no parenthesis; Reason: simple logic)
+
+In a subsequent message you wrote "have an interface_list in a derived
+type definition, then the parent must be tagged (which a task type is
+not)".  Hmm.  Unfortunately, a task type *may* be tagged, precisely if it
+is derived from one or more interfaces (that's important for Class to
+work, see 3.9(2.1)).  So we need to say that the parent is not a tagged
+task or protected type.  It would be simple enough to say "if and only if
+the parent type is a tagged record type".  But what about privacy?
+Consider:
+
+	package P is
+	   type T is tagged limited private;
+	private
+	   task type T is new I with ...
+	end P;
+
+	type NT is new P.T with ...; -- Legal?  Hopefully not!
+
+HELP!  What is it that makes NT illegal?
+
+> 3.4 (16) are there no predefined ops for interface types ?
+>     '(17/2) for equality, the rules are wrong!!!
+>         consider: parent is limited interface; some progenitor has a
+>               user-defined "=" (but is limited);
+>               does the resulting type inherit "=" ?
+>               The rules say "no", they should say "yes", because the
+>               progenitor has equality (and the type better not be
+>               without the "="!!!)
+
+I think you have a point here.  One option would be to say that if some
+progenitor has an "=" (user-defined or not) you cannot use it to declare a
+limited type.  Another option would be to say that if you declare a
+limited type you inherit any user-defined "=" as you would inherit any
+other user-defined operation.  I think I'd prefer the 1st option, as it
+would make the rules more uniform.
+
+> 3.9.1 3/2 2.sentence : parent -> the parent or a progenitor type !!
+>           (the sentence definitely applies to both)
+
+Agreed.
+
+> 3.9.3 (4/2) I could not parse the sentence in less than 3
+> minutes (and still am unsure of what it tries to say);
+
+Fair enough, but you cannot just groan, you have to propose a rewrite
+(have fun).
+
+> The argument in 4.5.2 (14.b/2) seems wrong: formal derived
+> types can also have parent types. Are they full types?
+
+Formal derived types don't have a parent, only a "ancestor subtype"
+(12.5.1(5/2)).
+
+> 7.6 Could Controlled become interface now ????
+
+It would be nice, but there are nasty problems associated with that.  For
+instance, you would have to assume that any object of a class-wide type
+could be controlled, because Controlled could be mixed in at any level.
+This wouldn't help code performance.
+
+> 9.1  (9.d/2)
+>    what is a name interface? how does the first part of the
+> sentence parse?
+>    missing "a" in "Only [a] limited"
+
+Here "name" is a verb and "interfaces" a noun.  I think the sentence is
+fine.
+
+> 12.5.1. (21/2) typo "progentor";  typo missing blank in "ancestoror"
+>         The content is bogus; apparently the "and progenitor" in the
+>         first sentence was added in the wrong place.
+
+Right.  The AI has the correct text.  Randy was tired.
+
+> Interface Interf;
+> procedure foo(X: Interf) is null;
+> procedure bar(X: Interf);
+
+(I won't comment on the weird syntax for declaring Interf ;-)  Bar must be
+abstract, because null and abstract are your only choices for primitive
+subprograms of interfaces.  Therefore...
+
+> But then, it'll come as a bloody
+> surprise that procedure test(X: Interf) is begin
+>      bar(X); -- dispatching call, of course
+>      foo(X); -- does not dispatch; does nothing
+> end test;
+
+... this is not even legal because the non-dispatching call to (the
+presumably abstract) Bar is a no-no.  So no bloody surprise here.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, May  9, 2005  1:59 PM
+
+> 	package P is
+> 	   type T is tagged limited private;
+> 	private
+> 	   task type T is new I with ...
+> 	end P;
+>
+> 	type NT is new P.T with ...; -- Legal?  Hopefully not!
+>
+> HELP!  What is it that makes NT illegal?
+
+Isn't that illegal by 3.9.4(10/2) (in the 13 April 2005 version)?
+
+> > 3.4 (16) are there no predefined ops for interface types ?
+> >     '(17/2) for equality, the rules are wrong!!!
+> >         consider: parent is limited interface; some progenitor has a
+> >               user-defined "=" (but is limited);
+> >               does the resulting type inherit "=" ?
+> >               The rules say "no", they should say "yes", because the
+> >               progenitor has equality (and the type better not be
+> >               without the "="!!!)
+>
+> I think you have a point here.  One option would be to say that if some
+> progenitor has an "=" (user-defined or not) you cannot use it to declare a
+> limited type.  Another option would be to say that if you declare a
+> limited type you inherit any user-defined "=" as you would inherit any
+> other user-defined operation.  I think I'd prefer the 1st option, as it
+> would make the rules more uniform.
+>
+
+I think I prefer the 2nd option.  Ada 95 allows user-defined "=" on
+limited types, and it can be inherited.  Wouldn't the 1st option above
+seem like an annoying arbitrary restriction?
+
+> > 7.6 Could Controlled become interface now ????
+>
+> It would be nice, but there are nasty problems associated with that.  For
+> instance, you would have to assume that any object of a class-wide type
+> could be controlled, because Controlled could be mixed in at any level.
+> This wouldn't help code performance.
+
+Isn't that already the case, since you can add controlled components?
+So even if the class-wide type is not itself controlled, it might need
+finalization.  (Yes, I agree that's an annoying efficiency hit -- but I
+think it already exists.)
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Monday, May  9, 2005  2:21 PM
+
+Pascal Leroy wrote:
+
+>>3.4 (16) are there no predefined ops for interface types ?
+>>    '(17/2) for equality, the rules are wrong!!!
+>>        consider: parent is limited interface; some progenitor has a
+>>              user-defined "=" (but is limited);
+>>              does the resulting type inherit "=" ?
+>>              The rules say "no", they should say "yes", because the
+>>              progenitor has equality (and the type better not be
+>>              without the "="!!!)
+>>
+>>
+>
+>I think you have a point here.  One option would be to say that if some
+>progenitor has an "=" (user-defined or not) you cannot use it to declare a
+>limited type.  Another option would be to say that if you declare a
+>limited type you inherit any user-defined "=" as you would inherit any
+>other user-defined operation.  I think I'd prefer the 1st option, as it
+>would make the rules more uniform.
+
+And I prefer the second option, as I think it provides a necessary
+capability.  Where you need it, it would be frustrating and error prone
+not to allow a user defined "=" to be inherited.  There are cases where
+copying of a type makes no sense, but equality (actually identity) is
+well defined and needed.  For example, I have some code that has to
+check if two elements of a task type are the same task.  (Yes, it is
+checking an error case where two parameters shouldn't be the same task
+from an array, but it is much clearer to pass the task objects as
+parameters rather than their indexes.  And of course due to the nature
+of abstractions, you have nested calling, etc.  )  So in this case, the
+*with* (or if you prefer the *use*) of Task_Identity is limited to the
+definition of "=" not spread throughout the code.
+
+Yes, I could overload some other operator, but we really shouldn't be
+going there.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, May  9, 2005  3:05 PM
+
+...
+> I think I prefer the 2nd option.  Ada 95 allows user-defined "=" on
+> limited types, and it can be inherited.  Wouldn't the 1st option above
+> seem like an annoying arbitrary restriction?
+
+I agree with Bob.  There should not be anything special about "=" --
+if you extend a limited interface that has "=" then you must
+override it.  I'm a little unclear why we need to say anything.
+Clearly if it has a predefined "=", then it is not a limited
+interface, so we are only talking about user-defined "=".
+
+>>>7.6 Could Controlled become interface now ????
+>>
+>>It would be nice, but there are nasty problems associated with that.  For
+>>instance, you would have to assume that any object of a class-wide type
+>>could be controlled, because Controlled could be mixed in at any level.
+>>This wouldn't help code performance.
+>
+> Isn't that already the case, since you can add controlled components?
+> So even if the class-wide type is not itself controlled, it might need
+> finalization.  (Yes, I agree that's an annoying efficiency hit -- but I
+> think it already exists.)
+
+Efficiency isn't the only problem.  J.P. Rosen brought this up
+several months ago, and alas, we had some pretty convincing
+reasons why we couldn't do this.  The main reason is that
+we don't allow "hidden" interfaces.  Right now, there are plenty
+of types that hide the fact they are controlled (e.g. Unbounded_String
+is likely to be implemented that way).  These would all become
+illegal if we made Controlled into an interface.  I tried to rethink
+whether we could allow "hidden" interfaces under certain circumstances,
+such as when all the primitives of the interface are null procedures,
+but that really didn't solve the problem.  The main issue is that
+if a type has a hidden interface, and then you extend the type and
+add an explicit derivation from that same interface, you are likely
+going to screw things up with the implementation of the hidden
+interface.  In particular, if someone implemented Controlled
+in a hidden way and defined Finalize to do something, if you
+then on some extension implement Controlled visibly, and override
+Finalize to do something completely different, the "hidden" Finalize
+operation is no longer going to be performed.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Monday, May  9, 2005  3:30 PM
+
+> > HELP!  What is it that makes NT illegal?
+>
+> Isn't that illegal by 3.9.4(10/2) (in the 13 April 2005 version)?
+
+Right, that prevents it.
+
+> > I think you have a point here.  One option would be to say that if some
+> > progenitor has an "=" (user-defined or not) you cannot use it to decl are
+> > a limited type.  Another option would be to say that if you declare a
+> > limited type you inherit any user-defined "=" as you would inherit any
+> > other user-defined operation.  I think I'd prefer the 1st option, as it
+> > would make the rules more uniform.
+>
+> I think I prefer the 2nd option.  Ada 95 allows user-defined "=" on
+> limited types, and it can be inherited.  Wouldn't the 1st option above
+> seem like an annoying arbitrary restriction?
+
+The second option seems better to me as well (more natural and flexible).
+
+> > > 7.6 Could Controlled become interface now ????
+> >
+> > It would be nice, but there are nasty problems associated with that.  For
+> > instance, you would have to assume that any object of a class-wide type
+> > could be controlled, because Controlled could be mixed in at any level.
+> > This wouldn't help code performance.
+>
+> Isn't that already the case, since you can add controlled components?
+> So even if the class-wide type is not itself controlled, it might need
+> finalization.  (Yes, I agree that's an annoying efficiency hit -- but I
+> think it already exists.)
+
+As Tuck points out (and as I was about to before I saw his message...),
+that's a no-go (because of the 3.9.4(10/2) rule you cited:).  Oh well.
+If it weren't for that restriction, I think you're right that the
+implementation wouldn't add any significant difficulty beyond what
+compilers already have to do for handling finalization on class-wide
+objects.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, May  9, 2005  3:50 PM
+
+> As Tuck points out (and as I was about to before I saw his message...),
+> that's a no-go (because of the 3.9.4(10/2) rule you cited:).  Oh well.
+> If it weren't for that restriction, I think you're right that the
+> implementation wouldn't add any significant difficulty beyond what
+> compilers already have to do for handling finalization on class-wide
+> objects.
+
+I disagree, there is a lot more complication. That's because type Controlled
+may have (hidden) components to provide the control data necessary for
+finalization. (I'd expect that to be a likely implementation, but I don't
+know of other compilers do that.) Interfaces don't have data. Making
+Controlled an interface would require the compiler to have some way to
+handle having data for interfaces. It would be aggrevating to have to
+implement that fully *and* not be able to use it for any other purpose.
+
+In addition, as Tucker pointed out, interfaces are essentially a Boolean
+proposition: either they are present or they are not present. That means
+that there is no way to deal with hidden overriding routines (there can be
+only one overriding), and certainly we don't want the incompatibility of
+requiring all controlled types to be visible.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Monday, May  9, 2005  6:41 PM
+
+> I disagree, there is a lot more complication. That's because type Controlled
+> may have (hidden) components to provide the control data necessary for
+> finalization. (I'd expect that to be a likely implementation, but I don't
+> know of other compilers do that.) Interfaces don't have data. Making
+> Controlled an interface would require the compiler to have some way to
+> handle having data for interfaces. It would be aggrevating to have to
+> implement that fully *and* not be able to use it for any other purpose.
+
+You're probably right that it has significant additional complications
+because of internal components on the root types.  Anyway, I wasn't
+trying to argue in favor of making those types interfaces, just that
+I thought it wouldn't be that hard if we didn't have the restriction
+(looks like I was probably wrong about that).
+
+> In addition, as Tucker pointed out, interfaces are essentially a Boolean
+> proposition: either they are present or they are not present. That means
+> that there is no way to deal with hidden overriding routines (there can be
+> only one overriding), and certainly we don't want the incompatibility of
+> requiring all controlled types to be visible.
+
+I wouldn't say there's no way of dealing with hidden overriding operations.
+The AARM discusses the alternatives and explains that the restriction
+is basically a methodological one.  The outside one could be defined to
+override, but I agree that we don't want that.  In short, I agree with
+the restriction requiring that inheritance from interfaces be visible.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, May  9, 2005  7:29 PM
+
+> Efficiency isn't the only problem.
+
+I wasn't arguing in favor of making Limited_[Controlled] an interface --
+just commenting on the efficiency point.  If nothing else, it's too
+late.
+
+I'm still interested in the technical issue, though.  In particular, if
+we weren't worried about compatibility, would the best solution be to
+make these types interfaces, and thereby forbid hidden controlledness?
+
+(I understand Randy's point about data in these types.)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, May  9, 2005  7:49 PM
+
+I think so, actually. I could imagine handling the data through background
+magic of some sort, and that wouldn't be so nasty if it had been designed in
+from the beginning.
+
+Similarly, if we weren't worried about compatibility at all, we'd probably
+use some other mechanism for data hiding (this one is pretty messy for OO),
+and hopefully eliminate problems with hidden inferfaces (so those would be
+allowed). [One possibility would be automated composition of primitives.]
+
+But of course that wouldn't resemble Ada that much (at least semantically),
+so this is rather off-topic.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, May  9, 2005  10:24 PM
+
+The "best" possible solution probably makes Initialize
+and Finalize into user-specifiable attributes, analogous
+to Read and Write.  And they would probably automatically
+compose, etc.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Monday, May  9, 2005  11:33 PM
+
+Is that a proposal for Ada1Z?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, May  9, 2005  11:50 PM
+
+Actually, it was a proposal for Ada 9X which never made it.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Tuesday, May 10, 2005  4:23 AM
+
+> And I prefer the second option, as I think it provides a necessary
+> capability.  Where you need it, it would be frustrating and error prone
+> not to allow a user defined "=" to be inherited.  There are cases where
+> copying of a type makes no sense, but equality (actually identity) is
+> well defined and needed.
+
+That makes sense.  Remember though that there is no code associated with
+interfaces, so any user-defined "=" has to be abstract.  So this
+capability is quite limited, although I can see that it would be useful at
+times.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, May 10, 2005  5:28 PM
+
+I did a double-take when I read that, then realized (I hope) that Pascal
+meant to say that subprograms in  interfaces are abstract and do not
+have explicit bodies.  Or am I wrong?  I looked at AI-251, and it says:
+
+All primitive subprograms must be abstract or null.
+
+Seems pretty clear. But haven't we been assuming that there is a
+(non-abstract) equality for non-limited interfaces?  It is probably
+reasonable to assume that 'Read and 'Write for interface types are
+abstract, but what about 'Class'Read and 'Class'Write?
+
+I had just assumed that I could write:
+
+package P is
+
+   type I is interface;
+
+   package Ops is
+      function "="(Left, Right: I) return Boolean is
+      begin return Left'Address = Right'Address; end "="
+   end Ops;
+
+end P;
+
+It would be nice to be able to dispense with the package Ops, but now I
+am begining to wonder if there are any predefined operations or
+attributes for interface types.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, May 10, 2005  5:42 PM
+
+> Seems pretty clear. But haven't we been assuming that there is a
+> (non-abstract) equality for non-limited interfaces?
+
+Predefined-equality is weird, but Tucker concluded it worked OK. And
+interfaces make my head hurt. :-)
+
+> It is probably
+> reasonable to assume that 'Read and 'Write for interface types are
+> abstract, but what about 'Class'Read and 'Class'Write?
+
+The stream attributes have their own rules; they're always around, but in
+some cases you can't call them. There was little consideration of
+abstractness and stream attributes in the first place.
+
+Anyway, go read the availability rules in 13.13.2(39-49/2) in the draft 11
+AARM. You should be able to figure out any answer about stream attributes
+there (although they might make *your* head hurt); if you can't, then tell
+us what you think the hole is.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, May 10, 2005  9:56 PM
+
+>Predefined-equality is weird, but Tucker concluded it worked OK. And
+>interfaces make my head hurt. :-)
+>
+I think the problem is that the reserved word appears in the wrong
+place.  Technically interface *types *appear in interface* packages.
+*How do you know that a package is an interface package?  Because it
+contains interface types.  I would much prefer for the syntax to
+require: *interface package* Foo *is*... *type* Bar *is interface*;...
+*end* Foo;  Just syntactic sugar, but it would make it clear that this
+is a funny kind of package because it contains interfaces.
+
+>Anyway, go read the availability rules in 13.13.2(39-49/2) in the draft 11
+>AARM. You should be able to figure out any answer about stream attributes
+>there (although they might make *your* head hurt); if you can't, then tell
+>us what you think the hole is.
+
+I'll do that, and if I have trouble I'll tell you where the new hole in
+my head is. ;-)
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, May 11, 2005  3:53 AM
+
+> Seems pretty clear. But haven't we been assuming that there is a
+> (non-abstract) equality for non-limited interfaces?
+
+There is certainly a non-abstract equality for non-limited interface, and
+it returns True (much like for a null record) and it get incorporated into
+the "=" for types whose parent is the interface.
+
+> It is probably
+> reasonable to assume that 'Read and 'Write for interface types are
+> abstract, but what about 'Class'Read and 'Class'Write?
+
+Don't assume anything!
+
+For interfaces, just like for any good old abstract type, 'Read and 'Write
+are non-abstract, and they read/write the non-tag components.  Not too
+useful because there isn't any, but well-defined.
+
+'Class'Read and 'Class'Write dispatch, so they never call the attributes
+for an interface.  Fine.
+
+'Input and 'Output behave much like 'Read and 'Write, 'cause there isn't
+any discriminant to read/write.
+
+'Class'Input and 'Class'Output read/write the tag of the parameter (which
+is never the tag of an interface) and then dispatch.  Fine.
+
+So I see no definitional problem here.
+
+> I had just assumed that I could write:
+>
+> package P is
+>
+>    type I is interface;
+>
+>    package Ops is
+>       function "="(Left, Right: I) return Boolean is
+>       begin return Left'Address = Right'Address; end "="
+>    end Ops;
+>
+> end P;
+>
+> It would be nice to be able to dispense with the package Ops,
+> but now I
+> am begining to wonder if there are any predefined operations or
+> attributes for interface types.
+
+The above is certainly legal, but the "=" is not primitive and hence not
+inherited.  It can only be called explicitly using view conversions.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Wednesday, May 11, 2005  2:10 PM
+
+>The above is certainly legal, but the "=" is not primitive and hence not
+>inherited.  It can only be called explicitly using view conversions.
+
+Understood.  I don't know why this misfeature is required (I must
+declare a non-primitive "="), but it is.   Yes, I know that it would
+'cause problems' if a derived type inherited two non-abstract
+subprograms with the same signature.  I just think that requiring such
+subprograms to be overridden--i.e. make them abstract--would be much
+more user friendly.
+
+However, what I was getting at in the example was that I should be able
+to (and I can) write subprogram definitions that take parameters of the
+interface type, and use attirbutes and subprograms with that notation
+(such as Inf'Read) inside the subprogram body.   This rule means that I
+will have to write 'wrappers' to make the calls look reasonable, but at
+least I can have an interface that results in *one* copy of the actual
+algorithm.
+
+I can write a package that provides a sort routine through inheritance?
+
+package Quicksort is
+
+  type Sortable is interface;
+
+  package Ops is
+    function ">"(L,R: Sortable) return Boolean;
+  end Ops;
+
+  generic
+    type Index is (<>);
+    type Element is private;
+    type To_Be_Sorted is new Sortable;
+    with function Indexed_Element(S: To_Be_Sorted; I: Index) return Element;
+    with procedure Set_Element(To: Element; S: in out To_Be_Sorted; I: Index);
+  procedure Sort(Arr: in out To_Be_Sorted);
+
+end Quicksort;
+
+Not too painful, and I hope legal.  Hmmm.  The more elegant approach may be:
+
+package Sortable_Arrays is
+  type Element is interface;
+  type Array_Of is array (Integer range <>) of Element'Class;
+  generic
+    with function ">"(L,R: Element) return Boolean;
+  procedure Sort(Arr: in out Array_Of);
+end Sortable_Arrays;
+
+But I have a suspicion that even if this 'works' there will be too much
+unnecessary tag checking to be efficient.   We then come full circle to:
+
+generic
+  type Element is private;
+  with function ">"(L,R: Element) return Boolean;
+package Sortable_Arrays is
+  type Array_Of is array (Integer range <>) of Element;
+  procedure Sort(Arr: in out Array_Of);
+end Sortable_Arrays;
+
+(Add a generic index parameter if you like.)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, May 11, 2005  5:50 PM
+
+...
+> Understood.  I don't know why this misfeature is required (I must
+> declare a non-primitive "="), but it is.
+
+Probably because it makes no sense to declare a concrete operation for a
+type with no components or objects. What useful could you possibly write in
+the body?
+
+> Yes, I know that it would
+> 'cause problems' if a derived type inherited two non-abstract
+> subprograms with the same signature.  I just think that requiring such
+> subprograms to be overridden--i.e. make them abstract--would be much
+> more user friendly.
+>
+> However, what I was getting at in the example was that I should be able
+> to (and I can) write subprogram definitions that take parameters of the
+> interface type, and use attirbutes and subprograms with that notation
+> (such as Inf'Read) inside the subprogram body.   This rule means that I
+> will have to write 'wrappers' to make the calls look reasonable, but at
+> least I can have an interface that results in *one* copy of the actual
+> algorithm.
+
+You can write such things, but IMHO they're always wrong. A non-primitive
+operation on a tagged type should have parameters of the appropriate
+class-wide type almost all of the time. That should be true in any case
+where allowing extensions of the type are expected. The exceptions to this
+rule are for cases like constructors, where extensions are discouraged or
+(as for function results) impossible.
+
+(The notion that 'Class has something to do with dispatching is one of
+largest dis-services done to Ada 95 users. It's all about extensions; yes,
+you need something class-wide to get dispatching, but it has many uses that
+have nothing to do with dispatching.)
+
+So, any such operation for interfaces (for which you cannot have
+constructors) should have 'Class as its arguments. We don't make using
+specific interfaces illegal because we don't want to deal with the generic
+contract problems that that would cause, but there is no reason to ever do
+it.
+
+> I can write a package that provides a sort routine through inheritance?
+
+Of course.
+
+> package Quicksort is
+>
+>   type Sortable is interface;
+>
+>   package Ops is
+>     function ">"(L,R: Sortable) return Boolean;
+>   end Ops;
+
+This makes no sense. Sortable has no components, so how could you
+meaningfully write a body for it. It is the users of this interface that
+have to provide the body.
+
+>   generic
+>     type Index is (<>);
+>     type Element is private;
+>     type To_Be_Sorted is new Sortable;
+>     with function Indexed_Element(S: To_Be_Sorted; I: Index) return
+Element;
+>     with procedure Set_Element(To: Element; S: in out To_Be_Sorted; I:
+Index);
+>   procedure Sort(Arr: in out To_Be_Sorted);
+>
+> end Quicksort;
+
+So I'd write this package like:
+
+package Quicksort is
+
+  type Sortable is interface;
+  function ">" (Left, Right : Sortable) return Boolean is abstract;
+
+   generic
+     type Index is (<>);
+     type Element is private;
+     type To_Be_Sorted is new Sortable;
+     with function Indexed_Element(S: To_Be_Sorted; I: Index) return
+Element;
+     with procedure Set_Element(To: Element; S: in out To_Be_Sorted; I:
+Index);
+   procedure Sort(Arr: in out To_Be_Sorted);
+
+end Quicksort;
+
+Except that it doesn't make sense to separate Sortable and the element type.
+So I'd suggest something like:
+
+package Quicksort is
+
+  type Sortable is interface;
+  function ">" (Left, Right : Sortable) return Boolean is abstract;
+
+  generic
+    type Index is (<>);
+    type Sortable_Element is new Sortable;
+    with function Indexed_Element(I: Index) return Element;
+    with procedure Set_Element(To: Element; I: Index);
+  procedure Sort;
+
+end Quicksort;
+
+But I'd really rather make this generic on the array type:
+
+package Quicksort is
+
+  type Sortable is interface;
+  function ">" (Left, Right : Sortable) return Boolean is abstract;
+
+  generic
+    type Index is (<>);
+    type Sortable_Element is new Sortable;
+    type Sorted_Array is (Index) of Sortable_Element;
+  procedure Sort (Arr: in out Sorted_Array);
+
+end Quicksort;
+
+But all of these interface solutions suffer from the fundamental failing of
+Interfaces: you can only have one copy of the interface (and, worse, only a
+specified name for the routine). So to allow differ sort orders, you'd have
+to build that into the Sorting procedure, since you can't build it into the
+interfaces. And you really don't want people to have to define a nonsense
+">" just so sorting works (because lots of other stuff would fail). So it
+would be best to avoid using the name ">" here. And perhaps best to just
+stick with a generic sort. (Especially since one comes with Ada 2006. :-)
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Wednesday, May 11, 2005  7:38 PM
+
+>>Understood.  I don't know why this misfeature is required (I must
+>>declare a non-primitive "="), but it is.
+>
+>Probably because it makes no sense to declare a concrete operation for a
+>type with no components or objects. What useful could you possibly write in
+>the body?
+
+An algorithm that 'makes sense'  once the (abstract or null) are
+overridden by operations for the type that inherits from the interface.
+
+>You can write such things, but IMHO they're always wrong. A non-primitive
+>operation on a tagged type should have parameters of the appropriate
+>class-wide type almost all of the time. That should be true in any case
+>where allowing extensions of the type are expected. The exceptions to this
+>rule are for cases like constructors, where extensions are discouraged or
+>(as for function results) impossible.
+
+Or as in one of my examples, where you want to *avoid *tag checks and
+dispatching.
+
+>>package Quicksort is
+>>
+>>  type Sortable is interface;
+>>
+>>  package Ops is
+>>    function ">"(L,R: Sortable) return Boolean;
+>>  end Ops;
+>>
+>>
+>
+>This makes no sense. Sortable has no components, so how could you
+>meaningfully write a body for it. It is the users of this interface that
+>have to provide the body...
+>
+>So I'd write this package like:
+>
+>package Quicksort is
+>
+>  type Sortable is interface;
+>  function ">" (Left, Right : Sortable) return Boolean is abstract;
+
+You are right, that is much better in this case, I was focusing on the
+situation I described above, where you can have a meaningful body in
+terms of other primitives.  For a non-realistic example:
+
+function ">" (Left, Right: Sortable) return Boolean is
+begin return Right < Left; end ">";
+
+Obviously this would be a bad thing to inherit.  I was thinking more in
+terms of algorithms like Runge-Kutta, Fast Fourier Transform, etc.
+
+>But all of these interface solutions suffer from the fundamental failing of
+>Interfaces: you can only have one copy of the interface (and, worse, only a
+>specified name for the routine). So to allow differ sort orders, you'd have
+>to build that into the Sorting procedure, since you can't build it into the
+>interfaces. And you really don't want people to have to define a nonsense
+>">" just so sorting works (because lots of other stuff would fail). So it
+>would be best to avoid using the name ">" here. And perhaps best to just
+>stick with a generic sort. (Especially since one comes with Ada 2006. :-)
+
+I was using Sort as a strawman.  One of the problems that I have with
+Ada today is trying to abstract algorithms from type specific code, so
+that you don't have to maintain several versions of the same algorithm.
+Unfortunately generics don't work, because you want Integer, Float, and
+Fixed versions--and sometimes Unsigned as well.  Yes, there are some
+cases where this is just not possible--code for fixed and floating
+matrix inversion needs to be very different.  But there are a few where
+you end up with two or more variables and a result that may be any of
+the three types.  (Well, I'm thinking mostly of distribution functions
+in statistics, the result domain is usually well defined as to type--for
+a particular distribution.  But there are cases where I should allow
+both float and fixed probabilities.)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, May 11, 2005  9:09 PM
+
+...
+> >Probably because it makes no sense to declare a concrete operation for a
+> >type with no components or objects. What useful could you possibly write in
+> >the body?
+> >
+> >
+> An algorithm that 'makes sense'  once the (abstract or null) are
+> overridden by operations for the type that inherits from the interface.
+
+OK, but to get to the overridden routines, you need dispatching. And to get
+dispatching, you want the parmeters to your operation to be class-wide. So,
+I ask again, what useful code could you write in the body of an operation
+with *specific* interface parameters?
+
+...
+> Or as in one of my examples, where you want to *avoid *tag checks and
+> dispatching.
+
+If you want to avoid dispatching, you can't use interfaces. They *only* work
+through dispatching. That's different than regular abstract types, which can
+have components and thus useful concrete operations.
+
+But really, dispatching is so cheap that it is silly to try to avoid it. The
+only valid reason is the use of tools that don't support it (like SPARK),
+and there I think the tools should be improved. You'd be better off avoiding
+generics (at least if you are using Janus/Ada) or discriminants controlling
+arrays.
+
+...
+> You are right, that is much better in this case, I was focusing on the
+> situation I described above, where you can have a meaningful body in
+> terms of other primitives.  For a non-realistic example:
+>
+> function ">" (Left, Right: Sortable) return Boolean is
+> begin return Right < Left; end ">";
+
+This is illegal, since "<" is necessarily abstract (functions can't be
+null), and thus cannot be called except in a dispatching call. (That makes
+it even more unrealistic than you had supposed. :-) If you had written:
+
+function ">" (Left, Right: Sortable'Class) return Boolean is
+begin return Right < Left; end ">";
+
+This would work fine, but then we wouldn't be having this conversation. :-)
+
+...
+> I was using Sort as a strawman.  One of the problems that I have with
+> Ada today is trying to abstract algorithms from type specific code, so
+> that you don't have to maintain several versions of the same algorithm.
+> Unfortunately generics don't work, because you want Integer, Float, and
+> Fixed versions--and sometimes Unsigned as well.  Yes, there are some
+> cases where this is just not possible--code for fixed and floating
+> matrix inversion needs to be very different.  But there are a few where
+> you end up with two or more variables and a result that may be any of
+> the three types.  (Well, I'm thinking mostly of distribution functions
+> in statistics, the result domain is usually well defined as to type--for
+> a particular distribution.  But there are cases where I should allow
+> both float and fixed probabilities.)
+
+True enough. There seem to be examples where Interfaces work fine. As long
+as the operations are well-defined and don't potentially conflict with
+normal practice. I usually use the queuing example as a strawman, since it
+is a much better fit for interfaces.
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent