CVS difference for ais/ai-10218.txt

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

--- ais/ai-10218.txt	2003/06/06 03:48:36	1.4
+++ ais/ai-10218.txt	2003/06/07 04:58:59	1.5
@@ -1,5 +1,5 @@
 !standard 8.3(26)                                    03-04-28  AI95-00218-02/04
-!class amendment 00-09-30
+!class amendment 02-09-30
 !status work item 02-09-30
 !status received 02-09-30
 !priority Medium
@@ -89,7 +89,7 @@
 
 The general idea is that subprogram declarations that are overriding are
 prefixed with "overriding" whereas subprogram declarations without this new
-syntax must not override another routine. The same applies torenamings and
+syntax must not override another routine. The same applies to renamings and
 generic instantiations. Special situations arise with generic packages and with
 private types.
 
@@ -318,7 +318,8 @@
 applying all checks in a generic declaration and then checking again as
 necessary for each instantiation.
 
-As a consequence "overriding" can never be used on operations of aderivation of a generic formal private type (as in the example), as no
+As a consequence "overriding" can never be used on operations of a
+derivation of a generic formal private type (as in the example), as no
 primitive operations are inherited from the formal type. Thus we write
 "overriding or not" so that the instantiation can allow overriding. Thus
 
@@ -1660,4 +1661,1739 @@
 
 *************************************************************
 
+From: John Barnes
+Sent: Wednesday, May 14, 2003  1:34 AM
+
+Attached is a rewrite of AI-218 on overriding.
+
+It captures a number of issues that I discussed with Randy
+and Pascal before revealing my inadequate understanding of
+Ada to the general public.
+
+I expect we will discuss it at length in Toulouse.
+
+[Editor's note: This is version /04 of the AI.]
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, May 14, 2003  8:15 AM
+
+I don't remember talking about "overriding or not"
+as the syntax.  It is a bit bizarre, but I'm sure
+Norm Cohen would love it, and I'm willing to play along.
+
+I note one "bug" in the discussion.  Formal derived
+private types do have one operation, namely "=",
+and presumably overriding should be used with
+that one.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, May 14, 2003  9:02 AM
+
+The minutes of the Padua meeting have:
+
+"We decide to put the keyword in front. John is asked to find a clever
+idea for the optional case."
+
+John tapped his indefatigable imagination and came up with this syntax
+for the optional case.  I must say that I like it better than anything
+that has been proposed so far.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, May 14, 2003  9:08 AM
+
+Those were jokes from Norm!
+
+I dislike this kind of keyword joke, except as a joke. I can't believe
+that someone would seriously suggest such ugly abuse of OR or NOT
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, May 14, 2003  10:50 AM
+
+I don't feel as strongly as Robert on this one,
+but here are some alternatives:
+
+   allow overriding
+   procedure blah(...);
+
+   possible overriding
+   procedure blah(...);
+
+   potential overriding
+   procedure blah(...);
+
+Of the three, I probably prefer "possible".
+"Allow" sounds like we are allowing overriding of this routine
+in subsequent descendants, rather than allowing this subprogram
+to be an overriding.
+
+I believe our latest thinking permits these only
+in the visible part of a generic package.  One possibility
+is to simply relax the rules and say that no overriding check is
+performed on an instance, making "possible overriding" the
+default in a generic, in other words.
+
+A third possibility is to make "possible overriding" the default
+in a generic, but allow an explicit "not overriding" prefix
+if desired, which is the default everywhere else.  In a generic,
+if given explicitly, "not overriding" means "not overriding even
+in the instance."
+
+E.g.:
+
+    type NT is new formal_type [with ...];
+
+    not overriding
+    procedure Blah(X : NT);
+
+means that Blah must not be overriding an operation that is
+inherited from formal_type, including in the instance.
+
+I suppose this third possibility is my mild favorite.  It allows
+users to be explicit everywhere if they like, and only in a generic
+is there a third option, which is between overriding and not overriding,
+requiring the "not overriding" to be explicit.
+
+One reason I prefer this is that it seems to me an unusual
+generic that really *cares* whether it is overriding in
+the instance.  I would rather not have to go and add
+"possible overriding" in all my generics, whereas I am
+quite happy to add "overriding" as necessary to be able
+to get additional checking.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, May 14, 2003  11:15 AM
+
+I must say that so far I preferred the pragma solution, I have no
+objection to a non-pragma solution if a decent syntax can be found,
+but so far I have not seen evidence of this.
+
+I also think a pragma solution is better because it allows
+earlier implementation, and also btter forwards/bacwards comatpiblity.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, May 14, 2003  11:52 AM
+
+I originally favored a pragma solution, but was convinced
+by how prevalent these annotations would be.
+Almost every dispatching operation that is not
+in the "root" type will need this annotation.
+That seems to make them inappropriate for a pragma,
+in my eyes, or at least a pragma having "good taste." ;-)
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, May 14, 2003  3:17 PM
+
+The real problem is that it isn't possible to solve the problem with pragmas
+alone, at least with the existing syntax of pragmas.
+
+John, Pascal, and I had a lengthy private discussion on this AI which we've
+since decided needed to be made public (since it covered a lot of annoying
+issues). One possibility which I will explore further is eliminating the
+pragmas and "optional overridding" altogether, by making the default be
+"don't care". This is slightly less safe, but it appears to be less
+complicated.
+
+In any case, this is a lot harder to do than it appears at first glance. Any
+solution works well in the 'typical' cases, but getting it right for
+generics and for private types with additional operations is hard.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, May 14, 2003  4:28 PM
+
+That seems amazing, because the only syntactic requirement for pragmas is
+that the arguments have the syntax of expressions (they can have any old
+seman6tics you want).
+
+*************************************************************
+
+From: David Emery
+Sent: Wednesday, May 14, 2003  4:35 PM
+
+Yeah, but I remember that the general intent of pragma-hood is to
+limit the effects of a pragma on legality or language-specific semantics.
+Doing this kind of thing with a pragma strikes me as A Bad Thing.
+
+Also, it strikes me that "override" and its verb forms are likely to
+appear as identifiers in existing real program:
+	if authorized or override then
+	   launch_the_missile;
+	else
+	  beep_annoyingly_at_operator;
+	end if;
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, May 14, 2003  6:32 PM
+
+Lots of pragmas affect legality, here is a partial list
+
+elaborate
+elaborate_body
+elaborate_all
+inline
+import
+convention
+restrictions (!)
+pack
+preealborate
+pure
+
+well that's off the top of my head
+
+Many others affect language-specific semantics
+
+remote_types
+suppress
+atomic
+volatile
+c_pass_by_copy
+locking_policy
+discard_names
+
+again that's off the top of my head
+
+Actually it takes more work to think up a list of pragmas that do NOT
+affect either legality or run-time semantics.
+
+So there may be good arguments against the use of a pragma, but this is
+not one of them!
+
+*************************************************************
+
+From: Gary Dismukes
+Sent: Wednesday, May 14, 2003  4:18 PM
+
+Tuck wrote:
+> I suppose this third possibility is my mild favorite.  It allows
+> users to be explicit everywhere if they like, and only in a generic
+> is there a third option, which is between overriding and not overriding,
+> requiring the "not overriding" to be explicit.
+
+The idea of making "possible overriding" the default for the
+generic case is attractive.  (Presumably this would only apply
+to primitives of types derived from formal types.)
+
+> One reason I prefer this is that it seems to me an unusual
+> generic that really *cares* whether it is overriding in
+> the instance.  I would rather not have to go and add
+> "possible overriding" in all my generics, whereas I am
+> quite happy to add "overriding" as necessary to be able
+> to get additional checking.
+
+I agree, it seems like it would be really annoying to have to
+apply the "possible" indication to all primitives in a generic.
+
+The drawback is that it's a little uncomfortable to have different
+defaults for the generic vs. normal case and the inconsistency
+has the potential to cause confusion.  However it does seem
+to make the feature easier to use.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, May 14, 2003   9:21 PM
+
+> The idea of making "possible overriding" the default for the
+> generic case is attractive.  (Presumably this would only apply
+> to primitives of types derived from formal types.)
+
+I think it need only apply for the check in an instance.
+There need not be any change in the semantics when compiling
+the generic itself.  Essentially, the default would be
+"this doesn't override any primitive in the generic,
+and I don't care whether it overrides any primitive in the instance."
+Explicitly saying "not overriding" would mean "this doesn't
+override any primitive in the generic, and it *also* doesn't
+override any primitive in the instance."
+
+The distinction between generic and instance only exists for a type
+derived directly or indirectly from a generic formal type,
+so the distinction between "" and "not overriding" only exists
+in a generic.  In all other contexts, they mean the same thing.
+
+
+> I agree, it seems like it would be really annoying to have to
+> apply the "possible" indication to all primitives in a generic.
+>
+> The drawback is that it's a little uncomfortable to have different
+> defaults for the generic vs. normal case and the inconsistency
+> has the potential to cause confusion.  However it does seem
+> to make the feature easier to use.
+
+If you take the approach I suggest above, the default
+is effectively equivalent to "not overriding" everywhere except
+in a generic, because only in a generic is there the distinction
+between the check on the generic and the check on the instance.
+
+*************************************************************
+
+From: Gary Dismukes
+Sent: Thursday, May 15, 2003  12:47 AM
+
+Makes sense, thanks for the clarification.  I'm in favor of this approach.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Wednesday, May 14, 2003  9:05 PM
+
+First let me say that my strong preference is that the default is may
+override.  If the keyword solution is preferred, for example,
+"overriding" means that this declaration must override, "not overriding"
+means that the subprogram must not override, and no keyword is status
+quo ante.  So this eliminates the need for the environment pragma, and
+answers all the potential questions about mixing new and old code.
+
+Robert Dewar wrote:
+
+> So there may be good arguments against the use of a pragma, but this is
+> not one of them!
+
+In fact I think that if we go with the default as may or may not
+override, there is a huge benefit to a solution using pragmas.  If the
+pragmas are present but the compiler used doesn't recognize the new
+pragmas?  No problem.  But the original proposal and variations requires
+  an upwardly incompatible change.  If the justification was strong, I
+might vote for a change that induced compatibility problems.  Making the
+default may or may not and using pragmas is totally upwardly compatible.
+  People who like the idea can start coding that way tomorrow.
+
+So I think that one of the major benefits of the pragma approach is this
+ability to start using the feature before compiler support is ready, and
+not have problems if, for example, your target compiler doesn't support
+the pragmas, but the compiler used for initial testing on the host does.
+  You get the benefit of the pragmas during development, and no worries
+that the source has to be modified for the target compiler.
+
+One last point.  There is a potential problem with the pragma approach
+when several declarations in the same declarative part have the same
+name.  I think that the pragmas should apply to all declarations with
+the same name, as most of the time that is exactly what will be desired.
+(For example, if you have  several Finalize operations declared in the
+same scope, it will be highly unusual to want only some of them to
+override.)
+
+But there needs to be a way to deal with the unusual case.  I think that
+I prefer that the pragma normally apply to all declarations in scope.
+But if there are two or more pragmas applying to the same name, the
+first should apply to declarations before its point of occurance, and
+the second declaration, should apply up to the point of its occurance
+and so on.  That way the pragma can be put directly after the
+declaration(s) it applies to.
+
+But in any case, you must have all three pragmas available (or a pragma
+with three arguments), independent of the default.  I prefer pragmas
+Overrides, No_Overriding, and May_Override.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, May 14, 2003   9:26 PM
+
+Robert I. Eachus wrote:
+> First let me say that my strong preference is that the default is may
+> override.  If the keyword solution is preferred, for example,
+> "overriding" means that this declaration must override, "not overriding"
+> means that the subprogram must not override, and no keyword is status
+> quo ante.  So this eliminates the need for the environment pragma, and
+> answers all the potential questions about mixing new and old code.
+
+That is the default in the absence of the pragma.  The
+whole point of the configuration pragma is to make
+the default "not overriding."  So if you prefer the
+default being "may override" then you won't use the
+configuration pragma.  But many people want the confidence
+that overriding happens only when explicitly requested.
+For them, the configuration pragma provides that.
+In fact, even if we didn't standardize it, I suspect the
+configuration pragma would be invented!  It is clearly
+a useful guarantee to provide in some environments.
+
+As far as going back to pragmas, please believe that that
+ground has been well tilled, several times.  Pragmas really
+don't work very well for various and sundry technical reasons, and having
+to use them pervasively I believe is a serious misuse of pragmas.
+
+You should definitely read the minutes from the past few meetings
+on this AI to fully understand the issues.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Thursday, May 15, 2003  1:22 AM
+
+Tucker Taft wrote:
+
+> You should definitely read the minutes from the past few meetings
+> on this AI to fully understand the issues.
+
+Oh, I understand the issue all right.  Let me sneak in one other
+advantage to pragmas, and then I will discuss why I think a pragma or
+pragmas is the right approach.
+
+If we use the pragma approach, then it is possible to have two
+variations which will make the pragmas much more useful.  The first is
+that if the pragma does not contain a subprogram name, or a list of
+subprogram names if that is allowed, then the pragma should apply to all
+subprograms declared in the scope.  This is often what you want if you
+are creating a descendent of a tagged type in a package.  All of the
+subprograms declared in the scope are expected to be overloading.  But
+there are also cases where most of the subprograms are explicit
+overloads, but there are one or two operations added for this (OO not
+Ada) subtype.  So if the pragmas are allowed with no arguments, then a
+pragma with a specific argument will only apply to that name.
+
+Doing this would make using the feature much less obtrusive.  It is
+possible to go further, and allow type names as parameters to the
+pragmas.  This would mean that all operations of that type declared in
+this scope are expected to be overloading.  (Or non-overloading
+depending on the pragma used, but for type names the first will be much
+more common.)
+
+Okay, now to raise the flaming sword and cry havoc! on the pragma vs
+(non-)reserved word issue.  The purpose of these annotations (and
+whatever form they take, that is all they are) is to promote program
+correctness.  A good and just cause.  But if the feature is not used, it
+won't help.  And even more important, if there are a mixture of usage
+styles in the wild, then distributing Ada components becomes much more
+difficult, you need one version that uses the feature and one that does not.
+
+Now let's look at the world where instead of on a per library basis, the
+feature is used on a per unit basis.  Compilers can have all sorts of
+compilation unit pragmas, or more realistically compile time switches
+that control error and warning messages.  On an individual preference
+basis we will probably see ignoring missing pragmas, and warnings for
+missing pragmas as the two favorites.  Software development plans and
+style guides will probably require the pragmas to be present, even if
+you want the default (whatever that turns out to be).  But in all
+compiler modes, if one of the pragmas is present but violated, that
+should be reported as an error.
+
+If this is the way the world ends up, then those who are willing to pay
+the minor overhead of using the pragmas will be happy.  Development
+environments will have templates that supply the pragmas, and there will
+be tools to add the pragmas where they are missing.  (Useful perhaps,
+for lazy programmers, but more useful for converting existing software
+to use the feature.)
+
+But all of these features will blunt the usefulness of the feature.
+(Notice that this can happen just as well with the non-pragma version.)
+  What you really want is for the programmer to think, and tell the
+compiler what he thinks.  That is why I think that allowing the type
+name as a pragma argument is such a win.  When programmers declare a new
+derived tagged type, they will document their expectation--all
+overloading, no overloading, or some mix.
+
+It might be possible to change the language syntax to have a specific
+portion of the declarative part where overloading subprograms, and only
+overloading subprograms can appear.  But I think that begins to look
+more like C++ than Ada.
+
+Pragmas that apply to all the operations of derived tagged types in the
+scope I think will make the cost of the feature small to the programmer,
+and the likelihood that the programmer will think while he is using it
+fairly high.
+
+Oh, one last point.  Whether the pragma or non-reserved word sides win,
+the effect of applying the pragmas or non-reserved words to subprograms
+that are not operations of a derived tagged type should be an error
+outside of generics.  (I can see cases where you want to use them in
+generics package specifications even when it is not clear to the
+compiler that the applicable generic formal type will be tagged.  For
+generic formal packages, the compiler will know.)
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Thursday, May 15, 2003   8:25 AM
+
+The configuration pragma can be used library-wide, or
+on an individual source file (aka "compilation").
+I think this gives the flexibility needed, while
+also allowing the project-wide control if desired.
+
+Robert I. Eachus wrote:
+> Tucker Taft wrote:
+>
+>> You should definitely read the minutes from the past few meetings
+>> on this AI to fully understand the issues.
+>
+> Oh, I understand the issue all right...
+
+If so, then you should address the specific issues in the minutes
+before launching off on other topics!
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Thursday, May 15, 2003  11:44 AM
+
+If I there is something missing in the draft minutes of the Padua
+meeting, you should probably suggest adding it. Other than that, I think
+the arguments are summed up in version 2 of the draft AI as:
+
+"An advantage over pragmas is that the syntax is clearly part of the
+declaration whereas pragmas are not. In the alternative approach the
+pragmas had to immediately follow the declaration (with optional
+inclusion of the subprogram identifier) and required special rules for
+the pragmas to ensure that they only applied to the immediately
+preceding declaration. The normal rules would have been that the pragma
+applied to all overloaded declarations with the same identifier which
+would clearly be inappropriate. There are also dangers if the pragmas
+get separated from the declaration during program amendment if the
+identifier is not included and including it seems a burden."
+
+I thought those were the issues I was addressing. The first statement is
+obvious and an argument for the syntax change which I accept.  However,
+I think that the advantages of the all pragma approach outweigh the
+disadvantages.  I don't really buy the argument about special rules for
+pragmas being needed.  There will be cases where overriding and
+non-overriding subprograms with the same name make sense, for example, a
+Create operation.  My proposal does address that case.  The dangers
+mentioned in the last sentence I definitely disagree with.  With the
+pragma solution my choice would be to place the pragmas directly after
+the derived type declaration:
+
+type Foo is new Ada.Finalization.Controlled with private;
+pragma Overrides(Initialize, Finalize);
+
+As long as there is a rule/understanding by compiler vendors that it is
+an error when there is no corresponding declaration, this placement is
+much more useful to the maintainer.  As for the author, locating the
+pragma directly after the type declaration would be much more likely to
+mean that he thought about the overriding issue.
+
+Some bookkeeping if you will.  Placing the prama(s) directly after the
+type declaration (or after the full declaration in the private part)
+argues strongly for the configuration pragma Explicit_Overriding with
+the currently documented meaning.  That way you get some benefit from
+using the pragma Overrides even absent the Explicit_Overriding pragma,
+and the full benefit when the Explicit_Overriding changes the default
+from may override to does not override.  You still need the
+non-overriding and may override pragmas in both cases, and a compiler
+option to warn about potentially overriding subprograms which are not
+covered by a pragma.
+
+This causes a slight problem with the Explicit_Overriding pragma because
+you really need two versions.  My choice of how to do that would be to
+have two pragma arguments Strict and Mild, with Mild the default.  Mild
+would mean that the compiler would only flag as errors cases where an
+overriding declaration was not flagged as such, the strict version would
+require that all such declarations be explicitly flagged as overriding,
+non-overriding or don't care.  Back to my example above, I would expect
+the normal style under the strict version to be:
+
+type Foo is new Ada.Finalization.Controlled with private;
+pragma Overrides(Initialize, Finalize);
+pragma Non_Overriding(Foo);
+
+This would mean that Initialize and Finalize are overriden, and that
+there are other operations for Foo declared here that are non-overriding.
+
+Again I strongly feel that the best place for this information is right
+after the derived type declaration, or the full type declaration for
+private types where the full declaration is a derived type.  There will
+be cases where this preferred location can't be used or doesn't make
+sense, but I feel that is a decision for the programmer, not the ARG.
+
+Imagine a ten page package declaration where there is an overriding of
+Finalize on page 6.  That is at least as hard to find as the Finalise
+declaration used as an argument for this feature.  If the pragmas are
+located just after the type declaration, that is going to make things
+much easier for the maintainer, or for someone writing a package that
+further derives from the type in the hypothetical ten-page package
+declaration. (Text_IO is only five.)
+
+Which brings up one last point.  Are there any standard library packages
+that are going to need to change as a result of this AI?  I can't think
+of any current packages, but there are some proposed new container
+packages that will.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Thursday, May 15, 2003  1:43 PM
+
+> People who like the idea can start coding that way tomorrow.
+
+Also implementors who like the idea can implement it tomorrow :-)
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Thursday, May 15, 2003  4:37 PM
+
+I am sick and tired of rehashing the same arguments over and over again,
+so let me quickly say this:
+
+We tried with pragmas.  As a matter of fact, we wrote the AI with
+pragmas initially, for all the good reasons that were listed (again) in
+this thread.  As a matter of fact, this AI went all the way up to WG9
+and was approved.  It only had one minor problem: it was all wrong.
+
+In order to deal with complicated situations involving private types,
+you need to be able to designate one particular subprogram among a set
+of overloaded subprograms.  If you don't want to force users to add
+renamings all over the place, this means that you need a way to specify
+a subprogram parameter profile in a pragma, e.g.:
+
+	pragma Foo (function F (X : Float) return Boolean);
+
+That's new syntax, so if we have to have new syntax we might as well do
+it right.
+
+See the end of the appendix of
+http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00218.TXT?rev=1.14 for
+details.
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, May 15, 2003  7:43 PM
+
+Pascal said:
+> I am sick and tired of rehashing the same arguments over and
+> over again, so let me quickly say this:
+
+I had written essentially this same message when the power went off here,
+dumping it into the ether. Pascal's message had come before I redid it.
+
+One amplification to Pascal's message. Robert Eachus claims that you do not
+need separate identification of routines, having a simple one for all
+overloaded routines is sufficient. That is rubish. It is quite common in Claw
+for a derived type (subtype in O-O terms) to have routines with the same name
+and additional parameters. That's partially because of our minimalistic naming
+(we try to name routines "Add" as opposed to "Add_Key_to_List"). In such a
+case, usually the existing routine is overridden, and the new version with
+additional parameters is an overriding. A single pragma which specifies one or
+the other will not work in this case; using a pragma to specify "don't care"
+eliminates the added safety we're trying to gain.
+
+After all, this feature is intended to increase the safety of O-O programs
+by preventing unintended changes (the most important being when a routine
+which is intended to be overriding is not in fact overriding). If such
+safety requires the use of lots of extra declarations (such as renamings),
+or worse, changing the names of routines, it is not going to get used as
+much. After all, in a perfect world, all Ada code would use these
+"overridding indicators" on all subprogram declarations (which probably is
+how the language should have been designed in the first place - but this
+problem goes back to Ada 83 and before).
+
+Also, solving the problem by prohibiting these on subprograms in the visible
+part or some such doesn't make sense either, as most O-O types will be some
+sort of private type.
+
+I'm no longer convinced that an acceptable solution is possible for this
+problem (even using syntax); there's no hope for pragmas alone.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Thursday, May 15, 2003  8:56 PM
+
+> That's new syntax, so if we have to have new syntax we might as well do
+> it right.
+
+Actually you do not have to add new syntax, as DEC showed with its import
+and export pragmas, it is perfectly possible to specify a specific
+overloading in a pragma. However, it's not very attractive, so I understand
+this argument, nevertheless I think pragmas are preferable. The point is
+that the argument:
+
+> That's new syntax, so if we have to have new syntax we might as well do
+> it right.
+
+
+is convincing but erroneous, since it rests on a false assumption.
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, May 15, 2003  8:56 PM
+
+Fine. Feel free to make an update to the AI-00218.TXT proposal that covers
+all of the issues in the Appendix to John's recent proposal.
+
+I was the original author of the pragma proposal, and I will not work on it
+further (as author, of course I'll work on it as editor), as I believe that
+either John's proposal or the alternative that I've discussed privately are
+better solutions. The reasons are usability and implementability. Because
+the syntax is part of the subprogram declaration, the necessary checking can
+(indeed, must) be done when the declaration is processed. That means that
+all of the information is there to make the checking. With Janus/Ada, at
+least, we figure out the overridding (or not) when we process the
+declaration, assigning tag slots, then discard it all (its not stored). It
+can be figured out again later, but its painful to do (and error-prone).
+
+I also think it is more readable to use syntax for this, as it means that
+the specifiers can't get separated from the subprograms.
+
+The only question is whether syntax is too heavy. I don't think so, because
+this is a significant safety issue in Ada 95. Given that we're marketing Ada
+as having been designed to be safe, it is rather embarassing to have the
+'wrong' routines to be called without being detected by the compiler.
+
+(The other such issue, default initialization of scalar and array objects,
+probably ought to be looked at again. But that is a case of something that
+was looked at in Ada 95 and explicitly decided not to fix. So I'm not sure
+of any benefit of reopening it.)
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Friday, May 16, 2003  1:39 AM
+
+> Actually you do not have to add new syntax, as DEC showed with its import
+> and export pragmas, it is perfectly possible to specify a specific
+> overloading in a pragma. However, it's not very attractive, so I understand
+> this argument...
+
+One of the issues was that we didn't want to come up with something that
+would look bolted-on five years from now.  Having to pepper a
+specification with complicated pragmas doesn't look too appealing now,
+it will be really ugly in 2008.  Of course, I realize that this is an
+aesthetical argument.
+
+The most convincing argument in favor of pragmas is that you can start
+using them now, without compiler changes.  However, I'm not sure I
+entirely buy this.  Once we have agreed upon a syntax, it's an afternoon
+project for an implementer to add that new syntax (without any semantic
+checks) to their parser.  And there are less that half-a-dozen front-end
+technologies these days.  So if there is the slightest market demand for
+this, syntax support can be in compilers in no time (if there is no
+market demand the whole point is moot).  For any real-life project,
+starting to use this feature would be a conscious decision, carefully
+planned, and they might as well ask their favorite vendor for a parser
+patch.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Friday, May 16, 2003  3:37 AM
+
+> Actually you do not have to add new syntax, as DEC showed with its import
+> and export pragmas, it is perfectly possible to specify a specific
+> overloading in a pragma.
+
+I must also mention that this approach, which worked fine in Ada 83, is
+not-so-straightforward in Ada 95 because of the addition of anonymous
+access types.  The pragma:
+
+   pragma Export_Function (Foo,
+                           Parameter_Types  => Integer, access Boolean, Float,
+                           Result_Type      => String);
+
+does not follow the syntax rules because 2.8(3) only has name or
+expression, not access_definition.  I realize that you can invent a
+convention to handle this case, but it becomes quite distasteful.  Plus,
+you have to remember that we consider adding anonymous
+access-to-subprogram types as part of the amendment, and these types
+would be intractable using a pragma without new syntax.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Thursday, May 15, 2003  11:39 PM
+
+Randy Brukardt wrote:
+> Pascal said:
+
+>>We tried with pragmas.  As a matter of fact, we wrote the AI with
+>>pragmas initially, for all the good reasons that were listed (again) in
+>>this thread.  As a matter of fact, this AI went all the way up to WG9
+>>and was approved.  It only had one minor problem: it was all wrong.
+>>
+>>In order to deal with complicated situations involving private types,
+>>you need to be able to designate one particular subprogram among a set
+>>of overloaded subprograms.  If you don't want to force users to add
+>>renamings all over the place, this means that you need a way
+>>to specify
+
+> One amplification to this. Robert Eachus claims that you do not need
+> separate identification of routines, having a simple one for all overloaded
+> routines is sufficient. That is rubish. It is quite common in Claw for a
+> derived type (subtype in O-O terms) to have routines with the same name and
+> additional parameters.
+
+I think you guys threw out the baby with the bathwater.  I said in my
+initial message:
+
+"One last point.  There is a potential problem with the pragma approach
+when several declarations in the same declarative part have the same
+name.  I think that the pragmas should apply to all declarations with
+the same name, as most of the time that is exactly what will be desired.
+(For example, if you have  several Finalize operations declared in the
+same scope, it will be highly unusual to want only some of them to
+override.)
+
+"But there needs to be a way to deal with the unusual case.  I think
+that I prefer that the pragma normally apply to all declarations in
+scope. But if there are two or more pragmas applying to the same name,
+the first should apply to declarations before its point of occurance,
+and the second declaration, should apply up to the point of its
+occurance and so on.  That way the pragma can be put directly after the
+declaration(s) it applies to.
+
+"But in any case, you must have all three pragmas available (or a pragma
+with three arguments), independent of the default.  I prefer pragmas
+Overrides, No_Overriding, and May_Override."
+
+As far as I can see this solves all of the nasty examples that have been
+given.  There are times when it looks ugly in some of the more bizzare
+cases, but if multiple pragmas with the same name as an argument always
+apply to all preceding subprogram declarations with that name it works.
+  There are cases where this generalization of the must immediately
+follow rule makes the text elegant, and it is always possible to
+construct cases which require more than one pragma per explicit
+subprogam name.  I consider those cases examples of bad design but that
+is a  detail.  Let me show you how the examples cited by Randy and
+Pascal work:
+
+It is quite common in Claw for a derived type (subtype in O-O terms) to
+have routines with the same name and additional parameters. That's
+partially because of our minimalistic naming (we try to name routines
+"Add" as opposed to "Add_Key_to_List").
+
+type Widget is new ... with private;
+
+procedure Add(W: in out Widget;...);
+procedure Add(W: in out Widget;...);
+procedure Add(W: in out Widget;...);
+pragma Overrides(Add);
+
+procedure Add(W: in out Widget;...);
+procedure Add(W: in out Widget;...);
+procedure Add(W: in out Widget;...);
+pragma No_Overriding(Add);
+
+Is that so horrible?  I could complain about all those Add operations,
+but that is your design choice.  Incidently notice that at first it
+seems unAdalike to have pragmas whose scope ends at the pragma.  But
+once you think about what these pragmas do, it makes perfect sense.
+These are assertions.  They don't change anything about the declarations
+they apply to, they just check that the asserted behavior is true, and
+if strict checking applies, they note that these declarations are
+correct.  My proposed rule allows the pragma to appear before the
+Overridings just to allow this case:
+
+   type Foo is new Bar with private;
+   pragma Overrides (Foo);
+
+This says that all of the subprogams which become operations of Foo,
+whether declared in the public part of a package or in the private part.
+It is legal, but from my perspective a bit naughty to do this, then in
+the private part say:
+
+private
+   function My_Create(...) return Foo;
+   pragma No_Overriding(My_Create);
+   ...
+
+I think that many style guides would frown on that, but that is the
+purpose of style guides, to frown appropriately. ;-)
+
+One of the troubling cases in version 1.14 of the write-up is:
+
+package P is
+     type T is tagged private;
+private
+     procedure P (Y : T);
+end P;
+
+package P.C is
+     type NT is new T;
+     procedure P (Y : NT);
+     pragma Overrides (P);   -- Could use Might_Overrides here,
+                             -- so privateness is not broken.
+private
+     -- Overrides here P.
+end P.C;
+
+You get to choose between lying publicly, or exposing private details.
+With my scheme, the appearance of the pragma can be delayed:
+
+package P is
+     type T is tagged private;
+private
+     procedure P (Y : T);
+end P;
+
+package P.C is
+     type NT is new T;
+     procedure P (Y : NT);
+     --  No pragma here, so privateness is not broken.
+private
+     pragma Overrides (P);   -- In the private part, the
+                             -- private part of P is visible
+                             -- so pragma makes more sense here.
+end P.C;
+
+As for this example, I am on very shaky ground about what is wanted:
+
+pragma Explicit_Overridding;
+package P is
+    type T is private;
+    function "+" (Left, Right: T) return T;
+    pragma Optional_Overriding("+"); -- So there is no check here.
+private
+    type T is range 0 .. 100;     -- "+" overrides
+    function "+" (Left, Right: T) return T; -- A redeclaration.
+    pragma Overrides ("+");
+end P;
+
+Apparently the assumption is that overriding behavior must be specified
+even for types that are neither tagged types or derived types, and for
+implicitly declared operations.  Also that there is some reason for
+explicitly lying in the public part of the package declaration.  I don't
+agree with any of that. If you feel it is needed how do you do it with
+the changed syntax proposal?  If I am missing the point of the example
+please explain it to  me.  Especially since Randy said:
+
+"The main advantage of the pragmas only proposal was that no new syntax
+or semantics (other than the check itself) is needed. That no longer
+appears to be the case, so I have reluctantly abandoned this alternative
+of the AI."
+
+But if I do understand the intentions of the example, with my solution
+you can put the pragma where it makes sense:
+
+pragma Explicit_Overridding;
+package P is
+    type T is private;
+    function "+" (Left, Right: T) return T;
+    -- No pragma here.
+private
+    type T is range 0 .. 100;  -- "+" overrides
+    -- No redeclaration here.
+    pragma Overrides ("+");    -- applies to "+" in visible part
+end P;
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Friday, May 16, 2003  5:20 AM
+
+There was at least one other problem, which had to do with
+subprograms which were not overriding in the visible part,
+but which were overriding in the private part, although the
+subprogram was itself declared in the visible part.  This was
+felt to be one of the final "nails" in the pragma "coffin,"
+as it effectively *required* that the pragma be separated
+from the subprogram spec, making the "placement" approach
+to identifying one subprogram no longer sufficient.
+
+Although we were all aware that Dec/Compaq/HP came up with a way
+to allow pragmas to specify particular subprograms among
+a group of overloaded subprograms, we all felt that this
+problem ultimately *deserved* syntax.  Having made that decision
+(now several meetings ago, though it was rehashed in Padua), we moved
+on to deciding on the best syntax.
+
+Although it is sometimes fruitful to re-open certain decisions if
+there are some new insights, I haven't heard anything sufficiently
+new here to justify re-opening this one.  We really have gone
+through this decision process quite carefully, and we reached a
+consensus.  I realize that if someone didn't attend an ARG meeting
+they couldn't contribute or not contribute to such a consensus, but
+that is the way these things tend to work.  Sometimes when a decision
+is still tentative, it can be kept open long enough to allow
+non-attendees to make some important contributions, but at least
+for this one, that would have had to have been a while ago.
+
+Now I think we should focus on the syntax, and try to get it right,
+rather than swinging back around to the starting point.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Friday, May 16, 2003  6:03 AM
+
+I must say I can't see any significant problem with Robert (Eachus) proposal,
+but perhaps I am missing something.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Friday, May 16, 2003  9:51 AM
+
+Robert Dewar wrote:
+> I must say I can't see any significant problem with Robert (Eachus) proposal,
+> but perhaps I am missing something.
+
+I feel the same way.  I think the proposal I put on the table solves the
+problems that caused the pragma approach to be dropped.  And as far as I
+can see, the current synax change proposal doesn't.  So either I am
+doing a bad job explaining it, or we are missing something...
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Friday, May 16, 2003  6:14 AM
+
+and they might as well ask their favorite vendor for a parser
+patch.
+
+But a "parser patch" is non-conforming, so either has to be under a special
+switch, or we have to wait till the entire WG9 approval process is complete.
+
+The pragma proposal can be implemented in a couple of hours, but of course
+it's not such a good idea to do this if the ARG is still twiddling its thumbs
+on the issue.
+
+I must say I would be more receptive to the syntax proposal if there was some
+decent syntax, and none of this OR NOT nonsense.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Friday, May 16, 2003  6:56 AM
+
+> does not follow the syntax rules because 2.8(3) only has name or
+> expression, not access_definition.  I realize that you can invent a
+> convention to handle this case, but it becomes quite distasteful.  Plus,
+> you have to remember that we consider adding anonymous
+> access-to-subprogram types as part of the amendment, and these types
+> would be intractable using a pragma without new syntax.
+
+I don't see the need for new syntax to handle this case, it would seem to
+be for example that integer'access would be an acceptable way of designating
+such a type.
+
+Interestingly, in GNAT we have all the DEC pragmas, and they are quite useful,
+e.g. for specifying that a specific argument be passed by reference.
+
+(obviously "quite useful" here is talking about rather specialized interface
+situations :-)
+
+That means that GNAT has a bug that we cannot differentiate in the case of
+access parameters, but not too surprisingly, no one ever reported this bug :-)
+
+I guess we should implement the type'access syntax in the context of these
+pragmas. Interesting (obviously we are not about to add new syntax).
+
+But indeed following this path for the overriding is getting unacceptably
+kludgy, so the only reasonable pragma approach would be that suggested
+by Robert Eachus.
+
+I am confused at this stage on the alternative, what is the latest greatest
+suggestion for concrete syntax additions to the subprogram declarations.
+
+By the way, the implementation burden of any syntax additions is always
+significant, compared to pragmas, so I strongly disgaree with Randy there.
+For syntax additions, you have to make changes to coding standards documents,
+pretty printers, editors that understand syntax, etc. The compiler changes are
+of course trivial, but that's never where the main work is for a change to the
+syntax.
+
+*************************************************************
+
+From: Robert Dewar
+Sent: Friday, May 16, 2003  7:18 AM
+
+> Although it is sometimes fruitful to re-open certain decisions if
+> there are some new insights, I haven't heard anything sufficiently
+> new here to justify re-opening this one.  We really have gone
+> through this decision process quite carefully, and we reached a
+> consensus.  I realize that if someone didn't attend an ARG meeting
+> they couldn't contribute or not contribute to such a consensus,
+
+Consensus in such an issue can be deceiving.
+
+After all the DR's had a very clear consensus that the syntax for what we
+now call tagged types should include the word class. We voted on that and
+it was a pretty close to unanimous vote.
+
+But in practice no one came up with a syntax that people found generally
+acceptable. More accurately, the prefix proposal narrowly failed because
+people did not like the syntax (indeed it should really have passed, because
+the Japanese delegation did not understand that by voting against it they
+would lose CLASS all together, which they really preferred, if Japan had
+voted positively, it would have passed 4-2).
+
+So what happened, is that from failure to find nice syntax for CLASS, we
+ended up with the peculiar keyword TAGGED, when there was a clear consensus
+against it.
+
+In this case, there is a consensus to use syntax. Sounds reasonable, I think
+I would have certainly signed up to this general notion.
+
+But then you have to come up with actual syntax, and if that actual syntax
+includes OR NOT, all I can say is that I find this as ugly as Tucker found
+the prefix CLASS syntax :-)
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Friday, May 16, 2003  7:23 AM
+
+Robert Dewar wrote:
+ > ...
+> I am confused at this stage on the alternative, what is the latest greatest
+> suggestion for concrete syntax additions to the subprogram declarations.
+
+For the basic case of overriding outside of a generic,
+we have pretty much settled on:
+
+   overriding
+   procedure Blah(...);
+
+This can be used in a private part, even if the subprogram
+is declared in the visible part, to indicate that the subprogram
+is overriding a privately-inherited operation.
+
+There is a configuration pragma (usable either library-wide or
+per source file) which specifies that the default
+is non-overriding.  In the absence of the pragma, the
+default is might or might not override (i.e. the current
+rule).
+
+What remains under debate is how to handle the case in
+a generic where the operation doesn't override in the
+generic, but it might or might not override in the instance.
+John proposed "overriding or not" as a way of allowing
+overriding in the instance.  I have countered with
+requiring the explicit use of "not overriding" in the
+(presumably rare) cases where you want to disallow overriding
+in the instance.  In the absence of explicit "not overriding",
+the default would be no additional check in the instance.
+As part of this, I would allow an explicit "not overriding"
+anywhere, as a way to be explicit, and to avoid any
+reliance on a configuration pragma's presence.
+
+Obviously this debate is still underway, and input on
+*this* issue would be very timely ;-)
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Friday, May 16, 2003  10:01 AM
+
+> type Widget is new ... with private;
+>
+> procedure Add(W: in out Widget;...);
+> procedure Add(W: in out Widget;...);
+> procedure Add(W: in out Widget;...);
+> pragma Overrides(Add);
+>
+> procedure Add(W: in out Widget;...);
+> procedure Add(W: in out Widget;...);
+> procedure Add(W: in out Widget;...);
+> pragma No_Overriding(Add);
+
+An approach like that was considered and rejected because we want people
+to be able to add overriding indicators to existing code relatively
+easily, and here they would have to reorder declarative parts which may
+be quite large.  Not only is that a lot of error-prone work, but it
+creates lots of spurious differences in versions control systems.
+
+Of course you could use the pragmas to delimit very small regions,
+containing only one or two subprograms, but that starts to look like
+C++, only uglier.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Friday, May 16, 2003  1:01 PM
+
+Pascal Leroy wrote:
+
+ > An approach like that was considered and rejected because we want
+ > people to be able to add overriding indicators to existing code
+ > relatively easily, and here they would have to reorder declarative
+ > parts which may be quite large.  Not only is that a lot of
+ > error-prone work, but it creates lots of spurious differences in
+ > versions control systems.
+
+I would rather say that it MAY result in a large number of changes in
+some cases.  But the syntax approach requires changing every one of the
+potentially overloading declarations.
+
+ > Of course you could use the pragmas to delimit very small regions,
+ > containing only one or two subprograms, but that starts to look like
+ > C++, only uglier.
+
+I agree with the aesthetics issue.  The question becomes when will the
+pragma approach get ugly.  For my code, one or two pragmas per derived
+tagged type is much preferrable to changing every subprogram
+declaration.  Others have different styles, as Randy explained, and I
+understand that.
+
+However, I still have yet to see how the current proposal solves the
+original problem.  That is what really concerns me.  Adding all the
+extra scaffolding of extra program declarations to me doesn't solve the
+original problem.  For example:
+
+with Ada.Finalization;
+package Root is
+     type Root_Type is tagged private;
+     procedure Do_Something (Object : in out Root_Type;
+                             Data : in Natural);
+private
+     type Root_Type is new Ada.Finalization.Controlled with null record;
+     not overriding
+     procedure Do_Something (Object : in out Root_Type;
+                             Data : in Natural);
+     -- additional declaration required by new rules.
+     overriding
+     procedure Finalize (Object : in out Root_Type); -- 2
+     -- Finalization hidden in private part to since Controlled is
+     -- hidden.
+end Root;
+
+with Root;
+package Leaf is
+    type Derived_Type is new Root.Root_Type with null record;
+    overriding
+    procedure Do_Something (Object : in out Derived_Type;
+                            Data : in Boolean); -- 1
+    not overriding
+    procedure Finalise (Object : in out Derived_Type);
+         -- Note: Alternative spelling of "Finalize".
+         -- and note that in the public view it is not overriding.
+end Leaf;
+
+with Leaf;
+procedure Sample is
+      Obj : Leaf.Derived_Type;
+begin
+      Leaf.Do_Something (Obj, 10); -- Calls (1).
+      -- Finalization of Obj will call (2).
+end Sample;
+
+-- Click BOOM!
+
+If you prefer, make the procedure Finalise a generic instantiation so
+that no declaration is needed in the body. So now we not only have the
+same old problem but I have to go to all that trouble to sign my own
+death warrant.  This is the problem I see with ANY solution that
+requires the overriding/non overriding declaration to located with the
+original declaration.
+
+Let's get a bit more heavy handed.  Require that if a type is private,
+that if a type is derived from it there has to be a private part in the
+package and a re-declaration of any overriding subprogams there:
+
+
+with Root;
+package Leaf is
+    type Derived_Type is new Root.Root_Type with null record;
+    overriding
+    procedure Do_Something (Object : in out Derived_Type;
+                            Data : in Boolean);
+    not overriding
+    procedure Finalise (Object : in out Derived_Type);
+         -- Note: Alternative spelling of "Finalize".
+         -- and note that in the public view it is not overriding.
+private
+    overriding
+    procedure Finalize (Object : in out Derived_Type);
+    -- Whoops, no error message on the body because this time I spelled
+    -- Finalize right.  But at least even if the original declaration of
+    -- Finalise is a generic instantiation, I'll get an error message
+    -- when compiling the body, or when I don't provide one.
+end Leaf;
+
+With my approach you will always get an error message on the package
+specification.  It may be a pretty confusing one if you have:
+
+
+with Root;
+package Leaf is
+    type Derived_Type is new Root.Root_Type with null record;
+    pragma Overriding(Derived_Type);
+
+    procedure Do_Something (Object : in out Derived_Type;
+                            Data : in Boolean);
+    procedure Finalise (Object : in out Derived_Type);
+         -- Note: Alternative spelling of "Finalize".
+         -- and note that in the public view it is not overriding.
+end Leaf;
+
+But you will always get one.  If you use:
+
+    pragma Overriding(Do_Something, Finalize);
+
+The error you will get will depend on how you spell the name in the
+pragma.  But at least you will get something.
+
+The reason I am so sensitive about getting an error message on the
+specification is that on large development projects, the specification
+may be written and agreed to months before there is a body.
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Friday, May 16, 2003  2:05 PM
+
+Robert I. Eachus wrote:
+ > ...
+> However, I still have yet to see how the current proposal solves the
+> original problem.  That is what really concerns me.  Adding all the
+> extra scaffolding of extra program declarations to me doesn't solve the
+> original problem.
+
+I'm afraid with all the to'ing and fro'ing, I have lost track
+of what is your "original problem."  If it is reflected in
+what comes below, I don't see a problem.
+
+
+For example:
+>
+> with Ada.Finalization;
+> package Root is
+>     type Root_Type is tagged private;
+>     procedure Do_Something (Object : in out Root_Type;
+>                             Data : in Natural);
+> private
+>     type Root_Type is new Ada.Finalization.Controlled with null record;
+>     not overriding
+>     procedure Do_Something (Object : in out Root_Type;
+>                             Data : in Natural);
+>     -- additional declaration required by new rules.
+>     overriding
+>     procedure Finalize (Object : in out Root_Type); -- 2
+>     -- Finalization hidden in private part to since Controlled is
+>     -- hidden.
+> end Root;
+>
+> with Root;
+> package Leaf is
+>    type Derived_Type is new Root.Root_Type with null record;
+>    overriding
+>    procedure Do_Something (Object : in out Derived_Type;
+>                            Data : in Boolean); -- 1
+>    not overriding
+>    procedure Finalise (Object : in out Derived_Type);
+>         -- Note: Alternative spelling of "Finalize".
+>         -- and note that in the public view it is not overriding.
+> end Leaf;
+>
+> with Leaf;
+> procedure Sample is
+>      Obj : Leaf.Derived_Type;
+> begin
+>      Leaf.Do_Something (Obj, 10); -- Calls (1).
+>      -- Finalization of Obj will call (2).
+> end Sample;
+>
+> -- Click BOOM!
+
+I have lost you here.  If a type is not *visibly* controlled
+somewhere within the immediate scope where the derived type is
+declared, there is no way you can override the Finalize operation,
+any way you spell it. See 7.3.1(6/1).
+
+> If you prefer, make the procedure Finalise a generic instantiation so
+> that no declaration is needed in the body. So now we not only have the
+> same old problem but I have to go to all that trouble to sign my own
+> death warrant.  This is the problem I see with ANY solution that
+> requires the overriding/non overriding declaration to located with the
+> original declaration.
+
+I still don't understand the problem.  We don't require
+the "overriding" annotation be on the original declaration.
+We allow an additional (re)declaration to be given in the
+private part if that is where the operation "becomes"
+an overriding. Below you have chosen to use "not overriding"
+explicitly, but that seems gratuitous, especially in this
+situation where you will be giving a contradictory (and wrong,
+given 7.3.1(6/1) annotation in the private part.  If we do
+allow the explicit "not overriding" I might be tempted to
+disallow it in a case where it becomes overriding in the
+private part, somewhat analogous to the suggestion for
+leaving it out in a generic when it might become overriding
+in the instance.
+
+
+> Let's get a bit more heavy handed.  Require that if a type is private,
+> that if a type is derived from it there has to be a private part in the
+> package and a re-declaration of any overriding subprogams there:
+>
+>
+> with Root;
+> package Leaf is
+>    type Derived_Type is new Root.Root_Type with null record;
+>    overriding
+>    procedure Do_Something (Object : in out Derived_Type;
+>                            Data : in Boolean);
+>    not overriding
+>    procedure Finalise (Object : in out Derived_Type);
+>         -- Note: Alternative spelling of "Finalize".
+>         -- and note that in the public view it is not overriding.
+> private
+>    overriding
+>    procedure Finalize (Object : in out Derived_Type);
+>    -- Whoops, no error message on the body because this time I spelled
+>    -- Finalize right.  But at least even if the original declaration of
+>    -- Finalise is a generic instantiation, I'll get an error message
+>    -- when compiling the body, or when I don't provide one.
+> end Leaf;
+
+This would get an error message because you can't override
+something you never have visibility on, per 7.3.1(6/1).  That would
+break "privateness."
+
+Perhaps you need to reconstruct your example, but as of
+now, I don't see the problem.
+
+
+>
+> With my approach you will always get an error message on the package
+> specification.
+
+This is nice, I suppose, but this example at least doesn't
+illustrate your point, and the advantage of having the
+error on the spec is pretty small, in my view at least.
+(And I have worked on some pretty big Ada systems...)
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Friday, May 16, 2003  6:42 PM
+
+Tucker Taft wrote:
+
+> I have lost you here.  If a type is not *visibly* controlled
+> somewhere within the immediate scope where the derived type is
+> declared, there is no way you can override the Finalize operation,
+> any way you spell it. See 7.3.1(6/1).
+
+Now my head really hurts!  Are you saying that the original derived
+Finalize declaration really can't be overridden and that in this case
+(or in this case with Finalize spelled right) dispatching still calls
+the implicit operation?  I hope not, and that this is just semantics.
+
+Let me create a better example (in current Ada):
+
+  with Ada.Finalization;
+  package Root is
+    type Root_Type is tagged private;
+    function Value (Object : Root_Type) return Integer;
+    procedure Set (Object : in out Root_Type; Value: in Integer);
+  private
+     type Root_Type is new Ada.Finalization.Controlled with record
+       Init_Case: Integer := 3; end record;
+    procedure Initialize (Object : in out Root_Type); -- 1
+    -- Finalization hidden in private part to since Controlled is
+    -- hidden.
+  end Root;
+
+  package body Root is
+    function Value (Object : Root_Type) return Integer
+    is begin return Object.Init_Case; end Value;
+
+    procedure Set (Object : in out Root_Type; Value: in Integer) is
+    begin Object.Init_Case := Value; end Set;
+
+    procedure Initialize (Object : in out Root_Type) is
+    begin Object.Init_Case := 1; end Initialize;
+
+  end Root;
+
+  with Root;
+  package Leaf is
+    type Derived_Type is new Root.Root_Type with null record;
+    -- derived type is known to be tagged but not controlled.
+    procedure Initialize (Object : in out Derived_Type); -- 2
+    -- Tucker says this is not overriding right?
+  end Leaf;
+
+  package body Leaf is
+    procedure Initialize (Object : in out Derived_Type)
+    is begin Set(Object, 2); end Initialize;
+  end Leaf;
+
+  with Leaf;
+  with Ada.Text_IO; use Ada.Text_IO;
+  procedure Sample is
+       Obj : Leaf.Derived_Type; -- Which Initialize gets called?
+  begin
+    case Leaf.Value(Obj) is
+    when 1 => Put_Line(" Root.Initialize Called.");
+    when 2 => Put_Line(" Leaf.Initialize Called.");
+    when 3 => Put_Line(" No initialization!");
+    when others => Put_Line(" I give up!");
+    end case;
+  end Sample;
+
+E:\Ada\Test\AI-218>sample
+  Leaf.Initialize Called.
+
+At least GNAT agrees with me. ;-)  Seriously I think that Tucker may be
+correct, "by the book."  But to not be able to declare Leaf.Initialize
+as overriding defeats the whole point.  Sigh.  So now even if we adopt
+my solution or the new syntax, we still have to change 7.3.1 to get the
+definition of overriding to agree with the commonsense definition.
+
+> I still don't understand the problem.  We don't require
+> the "overriding" annotation be on the original declaration.
+> We allow an additional (re)declaration to be given in the
+> private part if that is where the operation "becomes"
+> an overriding. Below you have chosen to use "not overriding"
+> explicitly, but that seems gratuitous, especially in this
+> situation where you will be giving a contradictory (and wrong,
+> given 7.3.1(6/1) annotation in the private part.  If we do
+> allow the explicit "not overriding" I might be tempted to
+> disallow it in a case where it becomes overriding in the
+> private part, somewhat analogous to the suggestion for
+> leaving it out in a generic when it might become overriding
+> in the instance.
+
+The first part certainly makes me happy.  I don't have to lie, I am just
+allowed to.  But we still have the problem.  If I go to my example above
+  and declare Leaf.Initialize, (or worse Leaf.Initialise) where can I
+declare it to be overriding?
+
+If my example makes your head hurt as much as mine does now, I
+apologize.  But I can now see why Tucker and I have been sparring at
+cross purposes.  In the example above, the compiler and author know that
+Leaf.Initialize is overriding (in the normal sense of the term) and that
+it will get called--by magic if you want to think of it that way--when
+an object of Leaf.Derived_Type is created.  My understanding has always
+been that the intention of this AI was to make that agreement between
+author and compiler explicit.  This will not only help insure that the
+author does in fact know what is going on, but will make it easier for
+readers to understand as well.
+
+But if ARM overriding does not have the commonly accepted meaning, then
+whether we go with a pragma or a syntax change to enforce that
+definition, in can only confuse the user.
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Friday, May 16, 2003  11:06 PM
+
+Robert Eachus wrote:
+
+> Let me create a better example (in current Ada):
+...
+> E:\Ada\Test\AI-218>sample
+>   Leaf.Initialize Called.
+>
+> At least GNAT agrees with me. ;-)
+
+I tried this on Janus/Ada 3.1.2, ObjectAda 7.2, and GNAT 3.15a1. GNAT does
+as you say (which is clearly wrong), and Janus/Ada and ObjectAda clearly say
+   "Root.Initialize Called"
+which is right.
+
+> Seriously I think that Tucker may be
+> correct, "by the book."  But to not be able to declare Leaf.Initialize
+> as overriding defeats the whole point.  Sigh.  So now even if we adopt
+> my solution or the new syntax, we still have to change 7.3.1 to get the
+> definition of overriding to agree with the commonsense definition.
+
+You're advocating the complete destruction of privateness, which you cannot
+mean. Clients of Root.Root_Type (including all of Leaf) do not know that
+Root_Type is controlled. Allowing them to override Initialize (on operation
+that the type does not have unless you peek into the private part) is a
+serious breach of privacy. So it's the case that Initialize is never
+overridding in your example, and declaring it to be so would be an error
+(precisely the sort of bug that this extra syntax is intended to detect).
+That means GNAT has a bug here, but we don't (in general) want to base the
+language rules on compiler bugs.
+
+Now, if Leaf was a child of Root (Root.Leaf), then the situation is
+completely different, and perhaps that is the case that you meant. In that
+case, the overridding occurs in the private part, and you would need to put
+the overriding clause in the private part.
+
+...
+> But we still have the problem.  If I go to my example above
+>   and declare Leaf.Initialize, (or worse Leaf.Initialise) where can I
+> declare it to be overriding?
+
+Nowhere, because it is never overridding.
+
+If you had Root.Leaf instead, you declare it to be overridding in the
+private part. No problem. There are even cases where you'd have to do that
+in the body. Ugly, but correct.
+
+> If my example makes your head hurt as much as mine does now, I
+> apologize.
+
+It only hurts because you seem willing to discard privateness, and I doubt
+that you meant to do that.
+
+> But I can now see why Tucker and I have been sparring at
+> cross purposes.  In the example above, the compiler and author know that
+> Leaf.Initialize is overriding (in the normal sense of the term) and that
+> it will get called--by magic if you want to think of it that way--when
+> an object of Leaf.Derived_Type is created.
+
+And the compiler has a bug, and the author is wrong. We HOPE that an error
+is detected in this case! This is precisely the sort of problem that AI-218
+was invented to solve, and I think your mistake here (and GNAT's)
+demonstrates nicely why this AI is important: the code may do silently do
+something other than is intended in a very subtle way.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Saturday, May 17, 2003  3:20 AM
+
+Randy reported:
+
+> I tried this on Janus/Ada 3.1.2, ObjectAda 7.2, and GNAT 3.15a1. GNAT does
+> as you say (which is clearly wrong), and Janus/Ada and ObjectAda clearly say
+>    "Root.Initialize Called"
+> which is right.
+
+Apparently Randy is still unable to run Apex.  For the record, Apex says
+"Root.Initialize Called" too, so there is consensus that the bug is in
+GNAT.  I am surprised that this case is not checked by the ACATS, btw,
+as it seems like a pretty serious issue.
+
+> You're advocating the complete destruction of privateness, which you
+> cannot mean.
+
+Right, I nearly had a heart attack when I read Eachus' message.
+
+> I think your mistake here (and GNAT's)
+> demonstrates nicely why this AI is important: the code may do silently do
+> something other than is intended in a very subtle way.
+
+I find it frightening that there may be code out there that depends on
+the GNAT behavior, and will behave differently when ported to another
+compiler (or when the ACT folks fix GNAT).  This is certainly a very
+strong justification for pursuing this AI.
+
+*************************************************************
+
+From: Robert I. Eachus
+Sent: Saturday, May 17, 2003  11:22 AM
+
+Pascal Leroy wrote:
+
+> Apparently Randy is still unable to run Apex.  For the record, Apex says
+> "Root.Initialize Called" too, so there is consensus that the bug is in
+> GNAT.  I am surprised that this case is not checked by the ACATS, btw,
+> as it seems like a pretty serious issue.
+
+> Right, I nearly had a heart attack when I read Eachus' message.
+
+Well at least since I was NOT surprised by GNAT's behavior, and expected
+it you can see why we have been arguing at cross-purposes.
+
+> I find it frightening that there may be code out there that depends on
+> the GNAT behavior, and will behave differently when ported to another
+> compiler (or when the ACT folks fix GNAT).  This is certainly a very
+> strong justification for pursuing this AI.
+
+No disagreement at all. But for the record what happens on the other
+compilers if:
+
+1) Root.Initialize is declared publicly, although Root_Type is still
+private?
+
+2) Leaf is a child of Root, but with a priavte part--which could
+possibly have nothing in it related to Derived_Type?
+
+3) package Leaf is a child of Root, but still without a private part?
+
+4) Same as above, but Initialize is declared by instantiating a generic
+subprogram from Root, so that Root.Leaf doesn't have a body either.
+
+5) The body of Root has a with clause for Leaf, but Leaf is not a child
+of Root.
+
+I think my understanding now is:
+
+1) Leaf.Initialize called, since it is overriding, although Root_Type is
+not visibly Controlled.
+
+2) Leaf.Initialize is called.
+
+3 & 4) Leaf.Initialize is also called. The AARM says: 7.3.1 (7.r) For
+all of these rules, implicit private parts and bodies are assumed as needed.
+
+5) Root.Initialize is called.  Anything else would be just too baroque.
+
+We definitely need this AI, and my reason for strongly favoring the
+pragma version now is that I need it with the GNAT bugfix.  It goes
+without saying that I have programs that depend on the current GNAT
+behavior.  I don't yet know if any will be broken by fixing the bug.
+(Other than this test case of course.)  Most should still be correct
+because tbey are the child package case, but I'd have to look.
+
+And of course, for non-experts who may not even know what the AARM is or
+where to find it, getting AI-218 implemented soonest is extremely
+important.  If language lawyers and compilers have trouble understanding
+the current rules (with AI-33 8652/0019 of course) non-experts will have
+no clue what to expect in these corner cases.
+
+*************************************************************
+
+From: Pascal Leroy
+Sent: Monday, May 19, 2003  8:37 AM
+
+Robert E. asked:
+
+> 1) Root.Initialize is declared publicly, although Root_Type is still
+> private?
+
+Leaf.Initialize Called.
+
+Now that Leaf knows that Root_Type has a primitive Initialize, it can
+override it.
+
+> 2) Leaf is a child of Root, but with a private part--which could
+> possibly have nothing in it related to Derived_Type?
+> 3) package Leaf is a child of Root, but still without a private part?
+
+Not sure exactly what you mean here.  If Leaf is a child of Root,
+Root.Initialize is declared in the private part, and Leaf.Initialize is
+declared in the visible part then:
+
+Leaf.Initialize Called.
+
+That's because, when you come to the private part of Leaf you discover
+that the parent type had a primitive Initialize, and overriding happens
+at this point.
+
+> 4) Same as above, but Initialize is declared by instantiating a generic
+> subprogram from Root, so that Root.Leaf doesn't have a body either.
+
+No bearing on the results, the fact that the primitive operation is
+declared by a normal subprogram or by an instantiation doesn't affect
+overriding.
+
+> 5) The body of Root has a with clause for Leaf, but Leaf is not a
+child
+> of Root.
+
+The with clause doesn't affect overriding, so assuming that
+Root.Initialize is declared in the private part:
+
+Root.Initialize Called.
+
+> It goes
+> without saying that I have programs that depend on the current GNAT
+> behavior.  I don't yet know if any will be broken by fixing the bug.
+> (Other than this test case of course.)  Most should still be correct
+> because tbey are the child package case, but I'd have to look.
+
+Yes, I guess that in most cases the derivation hierarchy will mimic the
+unit hierarchy, so the right thing will happen.  Your example is pretty
+uncommon in this respect.
+
+*************************************************************
 

Questions? Ask the ACAA Technical Agent