!standard 8.5.1(6) 07-12-06 AC95-00154/01 !standard 8.5.4(7) !class confirmation 07-12-06 !status received no action 07-12-06 !status received 07-11-27 !subject Historical question: why are constraints ignored in renamings? !summary !appendix From: John Barnes Sent: Tuesday, November 27, 2007 5:44 AM One of my colleaugues in the BSI has raised a question about renaming. He needs to refute someone who says that Ada is stupid. I apologise if this is not proper Ada 2005 business. But first let me recap the issue of default subprogram parameters because that might be relevant. In preliminary Ada, any default expression was evaluated when the subprogram spec was elaborated. It was like that in the 1979 SigPlan notices and in the July 1980 proposed standard The first edition of my book (early 1982) says that as well. There was a problem with matching spec and body if I recall correctly since the value might be different when the body was elaborated. As a consequence it was made dynamic and only evaluated when required. That was nice because the default spirit in one of my examples could then be Gin in the week and Vodka at weekends. This probably happened some time in 1982. Thus by July 1982 (draft revised mil std 1815) the manual had changed to say that the default expresion was evaluated when used. As it is now of course. Now with regard to renaming. The issue is why are constraints given by the renaming ignored and when did that happen? The 1979 preliminary Ada is pretty vague but hints that the constraints are unchanged - it doesn't say that new ones are ignored so perhaps it implies they have to match. The July 1980 proposd standard is much clearer and says that constraints must be the same (and raises C_E if they are not). The July 1982 manual says that constraints are unchanged by the renaming. Similarly, the first edition of my book (early 1982) says "at the time of elaboration of the renaming declaration any constraints must match". Whereas the second edition is as now and says new ones are ignored. The various rationales are unhelpful. And I can find no minutes of meetings from that time. Questions Were the two issues related? And why did we end up ignoring new constraints? (I usually mutter something about well you can just do a quick jump (into the ocean perhaps).) **************************************************************** From: Tucker Taft Sent: Tuesday, November 27, 2007 7:29 AM I had presumed that new constraints were ignored because of the equivalence with generic formal subprograms and formal IN OUT objects. It would be limiting to require the constraints to match for such generic formals, and since they are defined in terms of renaming, it would break the equivalence if renaming required exact matching. Here is another reason: before Ada 95, X'Base could only be used as the prefix of an attribute reference. In particular, it couldn't be used for the subtype of a formal parameter. However, the formal parameter subtype for the predefined operators are generally the base subtype, and if there is no way to state that, then renaming of predefined operators would not be possible. Of course times have changed, and we might consider tightening this up in the future. I suppose one step to that would be defining some kind of "restriction" in the High-Integrity annex requiring that constraints in renames must match. **************************************************************** From: John Goodenough Sent: Tuesday, November 27, 2007 10:43 AM Remarkably enough, I can answer this question. (Apparently it does pay to keep documents in your office for 25 years!) ------ On June 1, 1982, Kit Lester of the Language Design Team wrote a comment directly addressing why constraints are ignored in renaming: ******************************************* This comment paraphrases a discussion at the November 1981 DR's meeting, for those without access to the minutes (LSN.250, pages 6 and 7). See also comment #753 by George Romanski of Ada-Europe. Many users will be shocked that explicit constraints on type marks appearing in renaming declarations of objects or subprograms (or in generic formal declarations defined in terms of renaming) will be ignored. Eg: subtype POSITIVE is INTEGER range 1 .. NATURAL'LAST POS : POSITIVE; subtype SMALL is INTEGER range -9 .. +9; SML : SMALL renames POS; -- legal ... SML := 10; -- not small, but ok; shock SML := -1; -- small but raises CONSTRAINT_ERROR; shock Various restrictions on the type mark have been considered, but rejected: (1) The type mark must be unconstrained. Rejected because the type might be invisible where the subtype is visible, and because it would preclude writing subtype marks implying the same constraint. (2) Requring the type mark be followed by 'BASE; this is saying what is meant, but - gives an attribute returning a type (whereas at present 'BASE must be followed by another attribute, i.e., it modifies the following attribute rather than existing in its own right); and - requires radical syntax changes for renaming of subprograms with parameters or results, or an obscure restriction to achieve the same effect. (3) Demanding "equivalent constraints" requires new equivalence rules, including means for defining "sufficiently equal" floating point values resulting from different expressions. The alternative of not ignoring explicit constraints is also unacceptable; if the assignment SML := -1; in the above example did NOT raise CONSTRAINT_ERROR then the variable POS would have a negative value ... In summary: in the absence of an acceptable solution, the problem must be accepted. **************************************************************** From: Tucker Taft Sent: Tuesday, November 27, 2007 11:47 AM Interesting. It seems like all of the problems identified now have reasonable solutions in Ada 95, so we could probably shift toward requiring static matching of constraints. As I suggested in my earlier note, providing a "Restriction" in the High-Integrity Annex might be a good first step. **************************************************************** From: Robert A. Duff Sent: Tuesday, November 27, 2007 1:32 PM > Remarkably enough, I can answer this question. (Apparently it does pay > to keep documents in your office for 25 years!) Good to hear from you, John. Thanks for keeping those docs for 25 years! If you have machine-readable copies of these historical documents, I think it would be a good service to the community if you could get Randy to put them up on the web site. > (1) The type mark must be unconstrained. Rejected because the type > might be invisible where the subtype is visible, ... That part seems confused, to me. The same confusion that caused the language designers to make with_clauses intransitive. And not to allow with_clauses on private parts. >...and because > it would preclude writing subtype marks implying the same > constraint. Indeed. > - gives an attribute returning a type (whereas at present > 'BASE must be followed by another attribute, i.e., it > modifies the following attribute rather than existing in > its own right); Interesting that this rule was removed in Ada 95 (but we added a restriction on 'Base of composites). > - requires radical syntax changes for renaming of subprograms > with parameters or results, or an obscure restriction to > achieve the same effect. I've no idea what that means -- I don't see any syntactic issues. > (3) Demanding "equivalent constraints" requires new equivalence > rules, including means for defining "sufficiently equal" > floating point values resulting from different expressions. Interesting again -- we now have the concept of "static matching" on subtypes. And it nicely sidesteps the floating point issue. ;-) Now that we have this concept, the obvious rule is to require static matching, except that would be incompatible. Although as Tuck pointed out, it could be a Restriction. It could also be a compiler warning. **************************************************************** From: Robert A. Duff Sent: Tuesday, November 27, 2007 1:42 PM > One of my colleaugues in the BSI has raised a question about renaming. He > needs to refute someone who says that Ada is stupid. Maybe "stupid" is overstating the case, but this ignoring of subtypes on renamings is clearly a language design flaw, no matter what the original reasoning was. A relatively minor flaw. Perhaps your colleague should admit that Ada is imperfect. ;-) **************************************************************** From: John Goodenough Sent: Tuesday, November 27, 2007 1:57 PM > If you have machine-readable copies of these historical documents, I think it > would be a good service to the community if you could get Randy to put them > up on the web site. My files are, unfortunately, just in hard copy at this point. **************************************************************** From: Jeff Cousins Sent: Friday, May 23, 2008 5:47 AM One of the guiding rules of Ada is often said to be "no surprises". It therefore comes as some surprise that any constraints given by a renaming are ignored. For example: procedure Long_Name (X: Positive); … -- Conformance of constraints not enforced procedure Short_Name (Y : Integer) renames Long_Name; … Short_Name (-1); -- Compiles but raises Constraint_Error when run I am informed various restrictions on the type mark were considered, but rejected: " (1) The type mark must be unconstrained. Rejected because the type might be invisible where the subtype is visible, and because it would preclude writing subtype marks implying the same constraint. (2) Requring the type mark be followed by 'BASE; this is saying what is meant, but - gives an attribute returning a type (whereas at present 'BASE must be followed by another attribute, i.e., it modifies the following attribute rather than existing in its own right); and - requires radical syntax changes for renaming of subprograms with parameters or results, or an obscure restriction to achieve the same effect. (3) Demanding "equivalent constraints" requires new equivalence rules, including means for defining "sufficiently equal" floating point values resulting from different expressions. The alternative of not ignoring explicit constraints is also unacceptable; if the assignment SML := -1; in the above example did NOT raise CONSTRAINT_ERROR then the variable POS would have a negative value ... In summary: in the absence of an acceptable solution, the problem must be accepted. " Please could this matter be re-visited? Re (2), Ada 2005 has opened up some new possibilities, i.e. 'Base is now allowed on its own. Re (3), Constraints are most often applied to integer types, generally proving problematic in practice for floating types, so a solution that only applied to discrete types would still be a big step forward. **************************************************************** From: Randy Brukardt Sent: Friday, May 23, 2008 3:03 PM Based on the fairly recent ARG discussion (from which the ancient e-mail you quoted comes), there is no real technical problem here: Ada 95 added static matching rules (which Ada 83 did not want to do), and simply requiring static matching would work fine without the current anomolies. (And there would be no reason to have different rules for different kinds of types). However, this problem is mostly political. A change to require static matching on renames (and various generic formal parameters, for which the rules are intentionally the same as renaming) would be incompatible with all previous versions of Ada. How incompatible depends on how often this capability actually occurs in practice - my personal guess is that it is fairly common. I think most people rename operators without using 'Base, and that would become illegal if we adopt static matching. One could try to adopt some "holes" in the rule to avoid the most common incompatibilities, but that could get very complicated. Note that the null exclusion rules for renaming were adopted specifically to avoid surprises (rather than following the "tradition" of ignoring constraints), and they are very complicated (and for a simple on-off exclusion). In any case, the only incompatibilites that we will accept as language maintenance are those to fix outright bugs. It is not possible to argue that something that is explicitly in the Standard, and has been for 25 years, and has been confirmed several times, is a bug. Thus any such change would have to wait for the next major revision of Ada -- and there are no plans at this time for such a revision. So it will be many years before such an incompatible change could be considered, and several more before it would appear in compilers. **************************************************************** From: Dan Eilers Sent: Friday, May 23, 2008 3:31 PM > Thus any such change would have to wait for the next major revision of > Ada -- and there are no plans at this time for such a revision. This may be true. However, WG9's announcement and draft agenda for the upcoming meeting says there is a "current project to amend ISO/IEC 8652". See http://www.open-std.org/JTC1/SC22/WG9/n487.txt # Report of Ada Rapporteur Group: Edmond Schonberg, Chair # - including items related to the current project to amend ISO/IEC 8652 **************************************************************** From: Robert A. Duff Sent: Friday, May 23, 2008 5:24 PM > One of the guiding rules of Ada is often said to be "no surprises". > > It therefore comes as some surprise that any constraints given by a > renaming are ignored. You are right. This is a flaw in Ada. Unfortunately, I think you're decades too late. We can't fix this, because it would be severely incompatible. For ex: package P is type T is range ...; ... end P; with P; procedure Q is function "+" (X, Y : P.T) return P.T renames P."+"; would be illegal (P.T should be P.T'Base). I think you are a customer of AdaCore. You could request that AdaCore implement a warning in the "surprising" cases. The Ada RM doesn't really have the concept of "warning". On the other hand, AARM-2.8 says: Implementation Requirements 13 The implementation shall give a warning message for an unrecognized pragma name. 13.a Ramification: An implementation is also allowed to have modes in which a warning message is suppressed, or in which the presence of an unrecognized pragma is a compile-time error. On the third hand, "warning" and "error" are not defined in any formal or even semi-formal way, so the above is a rather questionable rule. **************************************************************** From: Jeff Cousins Sent: Wednesday, May 28, 2008 9:27 AM Thanks for your reply Randy. I appreciate the problem of backward compatibility. Could not there be a configuration pragma saying to check conformance, so that the default behaviour would be as before, but such that checking could be switched on? **************************************************************** From: Jeff Cousins Sent: Wednesday, May 28, 2008 9:28 AM Thanks Bob for your suggestion. GNAT does already give a warning in such problem cases. **************************************************************** From: Tucker Taft Sent: Wednesday, May 28, 2008 9:48 AM A "restrictions" pragma might be feasible. It sounds like your concerns are more about object renaming than about subprogram renaming, and a restriction requiring static matching of object subtypes in renaming would seem to be reasonable. Whether this needs to be de-jure standardized, or simply a de-facto standard I can't say. ****************************************************************