# CVS difference for ai12s/ai12-0075-1.txt

Differences between 1.5 and version 1.6
Log of other versions for file ai12s/ai12-0075-1.txt

```--- ai12s/ai12-0075-1.txt	2015/11/24 02:38:31	1.5
+++ ai12s/ai12-0075-1.txt	2017/10/12 04:36:52	1.6
@@ -466,3 +466,592 @@
address the original compatibility issue that Steve himself raised - Editor.]

****************************************************************
+
+From: Steve Baird
+Sent: Thursday, October  5, 2017  2:55 PM
+
+It seems clear that compatibility issues are a major concern associated with
+this proposal.
+
+We don't want examples which were previously legal to start running afoul of
+the "no check failures in a static expression" rule.
+
+Bob suggested one solution to this problem: an expression which fails the
+"no check failures" test becomes non-static, as opposed to illegal.
+
+But the consensus in Vienna (I am told) was that we also don't want to start
+allowing constructs which were previously illegal.
+
+There is a solution which satisfies both constraints, although I am not
+claiming that it is elegant: we relax the legality rules as per Bob's proposal
+but only in the case of a static expression that includes a call to an
+expression function. Such an expression could never currently be static, so
+this relaxation would not cause us to accept something that was previously
+rejected.
+
+So we would continue to disallow
+
+     N : constant := 0;
+   begin
+     if N /= 0 then
+        X := 10 / N;
+     end if;
+
+but we would also continue to allow
+
+    N : constant := 0;
+    function Ratio (X : Integer) return Integer is (X / N);
+  begin
+    if N /= 0 then
+      X := Ratio (10);
+    end if;
+
+====
+
+I was tasked with assessing the compatibility impact of an earlier version of
+this proposal, trying to somehow figure out how often situations like
+
+      procedure Foo is
+       function Inc (X : integer) return Integer is (X + 1);
+       subtype S is Integer range 0 .. Inc (3);
+       Y : S := ... ;
+    begin
+       -- if S is a static subtype then this case stmt is illegal
+       case Y is
+          when  0 .. 33 => ...;
+          when  44 .. 55 => ...;
+          when others => ... ;
+       end case;
+    end;
+
+arise in practice. I didn't get this done.
+
+====
+
+There is the point mentioned in the !discussion section of this AI:
+
+    3) Do we need to say anything about type invariants? No,
+    because if a function has a parameter (or result) of a private type,
+    then it's not a static function. But what if it is completed as
+    a static expression function after the private type is completed?
+    Maybe we need a rule saying that if a type invariant applies to
+    a function than the function is not a static expression function
+    (like the rule already given for predicates).
+
+I think we do need this rule.
+
+The AI says
+  A "static expression function" is defined to be an expression function
+     - ...; and
+     - ...; and
+     - ...; and
+     - ...; and
+     - ...
+
+I think we need to invent a term for the property implicitly defined in the
+section on type invariants
+    An invariant is checked upon successful return from any
+    call on a subprogram or entry that ...
+
+Something like
+     An entry or subprogram is said to be an "invariant
+     boundary" entry or subprogram if ...
+
+followed by a use of the new term
+
+     An invariant is check upon successful return from any
+     call on an invariant boundary subprogram or entry.
+
+Then we can use the new term to add a new clause to the definition of "static
+expression function" along the lines of
+    "which is not an invariant boundary subprogram; and"
+
+Other possible names for the new term: "invariant enforcing", "invariant
+checking".
+
+====
+
+Opinions?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, October  5, 2017  3:16 PM
+
+> It seems clear that compatibility issues are a major concern
+> associated with this proposal.
+
+Maybe for some folks.  Expression functions are pretty new!
+
+...
+> There is a solution which satisfies both constraints, although I am
+> not claiming that it is elegant: we relax the legality rules as per
+> Bob's proposal but only in the case of a static expression that
+> includes a call to an expression function. Such an expression could
+> never currently be static, so this relaxation would not cause us to
+> accept something that was previously rejected.
+
+That seems fine to me.
+
+> ...
+> I think we need to invent a term for the property implicitly defined
+> in the section on type invariants
+>   An invariant is checked upon successful return from any
+>   call on a subprogram or entry that ...
+>
+> Something like
+>    An entry or subprogram is said to be an "invariant
+>    boundary" entry or subprogram if ...
+
+I would somewhat rather associate the notion of boundary with the type being
+defined, rather than this one particular aspect that is checked at the
+boundary.  Perhaps simply "boundary subprogram for private type T" or
+"boundary subprogram for some partial view."  Getting the word invariant there
+muddies the waters a bit for me.  The concept of such a boundary exists even
+if no invariants have been defined explicitly.
+
+I suppose any term we pick would eventually grow on me... ;-)
+
+...
+> Other possible names for the new term: "invariant enforcing",
+> "invariant checking".
+
+I find these names even muddier...  I would like to describe the concept,
+without talking about what things might happen when crossing that border.
+Sort of like calling the border between two countries an "immigration control
+line."
+
+> ====
+>
+> Opinions?
+
+See above.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Thursday, October  5, 2017  3:41 PM
+
+>  I would somewhat rather associate the notion of boundary with the
+> type being defined,
+I like that idea too.
+
+IIRC, we have wanted a well-defined term for this for other reasons in the
+past.
+
+Would precisely defining the boundary for a type also help with the questions
+raised in AI12-0210 (Type Invariants and Generics)?
+
+It seems to me that the two issues are related.
+
+Roughly speaking, the idea we are trying to capture here is that a boundary
+subprogram for a given private type
+    a) can see the implementation of the private type; and
+    b) is callable from places that cannot see the implementation
+       of the private type; and
+    c) has a non-in-mode parameter or a function result of the type.
+
+Right?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, October  5, 2017  3:46 PM
+
+> > It seems clear that compatibility issues are a major concern
+> > associated with this proposal.
+>
+> Maybe for some folks.  Expression functions are pretty new!
+
+Two points on this:
+
+(1) My experience is that once one has expression functions and is used to
+the idea, one tends to write everything possible as an expression function.
+(This is a problem if you are writing Ada 2005 ACATS tests or for a compiler
+that doesn't support them. I've done both. :-)
+
+(2) This compatibility problem exists any time a regular function is changed
+into an expression function or vice-versa. It's not just a one time thing.
+
+In particular, I expect Janus/Ada customers to rewrite regular functions into
+expression functions in some cases, because Janus/Ada only supports inlining
+on expression functions. When that is done, they'd be at risk of running into
+speaking in the future tense here. :-)]
+
+...
+> > There is a solution which satisfies both constraints, although I am
+> > not claiming that it is elegant: we relax the legality rules as per
+> > Bob's proposal but only in the case of a static expression that
+> > includes a call to an expression function. Such an expression could
+> > never currently be static, so this relaxation would not cause us to
+> > accept something that was previously rejected.
+>
+> That seems fine to me.
+
+Cool. I predicted to Steve the opposite. (It is a rather clunky rule, and I
+thought you'd object to the "bolted-on" look of it.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, October  5, 2017  6:42 PM
+
+> Roughly speaking, the idea we are trying to capture here is that a
+> boundary subprogram for a given private type
+>   a) can see the implementation of the private type; and
+>   b) is callable from places that cannot see the implementation
+>      of the private type; and
+>   c) has a non-in-mode parameter or a function result of the type.
+
+I don't understand why you have that last bullet in that form.  Why does the
+mode matter?  And are you considering access parameters or access results?
+From a SPARK point of view, you will still be presuming the invariant is true
+on entry, which you will not be doing for local functions.
+
+> Right?
+
+
+****************************************************************
+
+From: Steve Baird
+Sent: Thursday, October  5, 2017  7:08 PM
+
+> I don't understand why you have that last bullet in that form.  Why does the
+> mode matter?  And are you considering access parameters or access results?
+> From a SPARK point of view, you will still be presuming the invariant is true
+> on entry, which you will not be doing for local functions.
+
+
+And even for others, I see your point.
+
+There are advantages to ignoring the parameter mode completely (as opposed to
+special rules for in-mode non-access parameters) and I don't see any
+disadvantages, even if no runtime check is performed in that case.
+
+And of course when I talked about a parameter/result of the private type, I
+should have been talking about a parameter/result of a type that has a part
+which is of that type.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, October  5, 2017  8:05 PM
+
+> Good point about access parameters.
+>
+> And even for others, I see your point.
+>
+> There are advantages to ignoring the parameter mode completely (as
+> opposed to special rules for in-mode non-access parameters) and I
+> don't see any disadvantages, even if no runtime check is performed in
+> that case.
+
+Right.  This is another reason I would be reluctant to include the word
+"invariant" in the term we end up using.
+
+> And of course when I talked about a parameter/result of the private
+> type, I should have been talking about a parameter/result of a type
+> that has a part which is of that type.
+
+You could argue that boundary subprograms need not have any parameters or
+results of the type.  The key point is that their body has more visibility
+on the type than their callers.  They might be passed an access value and
+follow it three steps to an object of the private type, and do their thing
+there.  SPARK as of today (prior to "safe" pointers) doesn't have this
+problem, but presumably in Ada we do have that situation, and SPARK with
+safe pointers might have it as well.  So I think the parameter profile might
+be irrelevant once you start having pointers.
+
+But now if we bring this back to expression functions -- can they be static
+if they have any parameters of an access type?  And I have lost track of what
+this whole thing was about -- why are invariant checks a problem?  We don't
+want to do them as part of static evaluation?  Why don't we say that a static
+expression function must not be the completion of a function declaration.
+Hence, if you want a function to be static, give the expression when it is
+declared.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, October  5, 2017  8:21 PM
+
+...
+> But now if we bring this back to expression functions -- can they be
+> static if they have any parameters of an access type?
+>  And I have lost track of what this whole thing was about -- why are
+> invariant checks a problem?
+
+From memory, we don't want any checks that might fail in a static function
+call. We disallow predicates, and Steve decided we needed to do the same
+for any invariant checks.
+
+Making the function visible without a completion doesn't completely
+eliminate the problem, as an invariant can be visibly defined and so can
+an expression function of a private type.
+
+Moreover, I already strongly dislike the fact that the implementation of a
+static function has to be exposed. It makes them go contrary to the basic
+point of Ada (a strong separation between specification and implementation).
+Making that problem worse doesn't improve the AI in my view.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, October  5, 2017  9:43 PM
+
+This surprises me.  What is the purpose of a static function if you don't
+know it is static and cannot use it as one?  At least with this AI, the only
+way you know that an expression function is a static function is by looking
+at its defining expression.  I suppose if there were an aspect "Static" or
+equivalent, then you could postpone the "body" of the expression function to
+the private part.  Am I missing something?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, October  5, 2017  10:01 PM
+
+> This surprises me.  What is the purpose of a static function if you
+> don't know it is static and cannot use it as one?
+
+One could argue "approximately the same as any other user-defined static
+function", but that's a discussion for a different time.
+
+... > At least with this AI, the only way you know that an expression
+> function is a static function is by looking at its defining
+> expression.  I suppose if there were an aspect "Static" or equivalent,
+> then you could postpone the "body" of the expression function to the
+> private part.  Am I missing something?
+
+There surely should be a "Static_Possible" aspect, which among other things
+would allow deferring the expression elsewhere (probably not to a body, though,
+as the compiler has to be able to see a static expression that it is
+evaluating). It certainly would be needed should we ever try to expand static
+processing to user-defined static expressions. (Jeff told me privately that
+the UK would like to see static expression processing regularized. I think
+we've already rejected that idea for this cycle, but I think we need to leave
+the possibility open.)
+
+***************************************************************
+
+From: Tucker Taft
+Sent: Thursday, October  5, 2017  10:57 PM
+
+> There surely should be a "Static_Possible" aspect, which among other
+> things would allow deferring the expression elsewhere (probably not to
+> a body, though, as the compiler has to be able to see a static
+> expression that it is evaluating).
+
+I am dubious.  Static expressions can affect legality, so you really have to
+know what the function is computing.  There really can't be any "abstraction"
+here to speak of.
+
+> It certainly would be needed should we ever try to expand static
+> processing to user-defined static expressions. (Jeff told me privately
+> that the UK would like to see static expression processing
+> regularized. I think we've already rejected that idea for this cycle,
+> but I think we need to leave the possibility open.)
+
+I think you are talking about a completely different AI than this one.  Given
+the current AI, there seems no particular value to allowing a static
+expression function to be a completion.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, October  5, 2017  11:11 PM
+
+...
+> I think you are talking about a completely different AI than this one.
+> Given the current AI, there seems no particular value to allowing a
+> static expression function to be a completion.
+
+Yes, a different (and future) AI. But I don't want this AI to prevent that AI
+from being possible.
+
+***************************************************************
+
+From: Tucker Taft
+Sent: Thursday, October  5, 2017  11:04 PM
+
+> Yes, a different (and future) AI. But I don't want this AI to prevent
+> that AI from being possible.
+
+Right.  But being *more* restrictive than absolutely necessary is our usual
+approach.  By requiring static expression functions to be defined where they
+are declared, we are keeping this AI simpler, and allowing ourselves to relax
+the restrictions later.
+
+***************************************************************
+
+From: Steve Baird
+Sent: Thursday, October  5, 2017  11:09 PM
+
+>   And I have lost track of what this whole thing was about -- why are
+> invariant checks a problem? We don't want to do them as part of static
+> evaluation?
+
+Exactly.
+
+>  Why don't we say that a static expression function must not be the
+> completion of a function declaration.
+
+Sounds like a nice clean solution; I like it.
+
+It is inconsistent with our treatment of deferred constants (because a use of
+a deferred constant can be static if the completion is visible), but that's ok
+I suppose.
+
+***************************************************************
+
+From: Steve Baird
+Sent: Friday, October  6, 2017  11:26 AM
+
+> It is inconsistent with our treatment of deferred constants (because a
+> use of a deferred constant can be static if the completion is
+> visible),
+
+Do we decide whether an expression function is a static expression function
+when the function is declared or when it is used?
+
+Consider:
+
+     package Pkg is
+        type T is private;
+        Dc : constant T;
+        function Expr_Func return T is (Dc);
+     private
+        type T is new Integer;
+        Dc : constant T := 0;
+        Named_Number : constant := Expr_Func; -- legal?
+     end;
+
+***************************************************************
+
+From: Randy Brukardt
+Sent: Monday, October  9, 2017  7:07 PM
+
+>> There surely should be a "Static_Possible" aspect, which among other
+>> things would allow deferring the expression elsewhere (probably not
+>> to a body, though, as the compiler has to be able to see a static
+>> expression that it is evaluating).
+
+>I am dubious.  Static expressions can affect legality, so you really
+>have to know what the function is computing.  There really can't be any
+>"abstraction" here to speak of.
+
+The only reason to write a static function in the first place is to provide
+some "abstraction". Else it is just useless complication for the reader. If
+you are right here, then there shouldn't be any static functions to begin
+with.
+
+...
+> >>> It certainly would be needed should we ever try to expand static
+> >>> processing to user-defined static expressions. (Jeff told me
+> >>> privately that the UK would like to see static expression
+> >>> processing regularized. I think we've already rejected that idea
+> >>> for this cycle, but I think we need to leave the possibility
+> >>> open.)
+> >>
+> >> I think you are talking about a completely different AI than this
+> >> one.  Given the current AI, there seems no particular value to
+> >> allowing a static expression function to be a completion.
+> >
+> > Yes, a different (and future) AI. But I don't want this AI to
+> > prevent that AI from being possible.
+>
+> Right.  But being *more* restrictive than absolutely necessary is our
+> usual approach.  By requiring static expression functions to be
+> defined where they are declared, we are keeping this AI simpler, and
+> allowing ourselves to relax the restrictions later.
+
+Such a future AI would have to have a way (almost certainly an aspect) to mark
+completions that are static functions. (A "generalization" proposal that
+doesn't support private types is not really fixing anything, IMHO.) An AI that
+has some sort of automatic static functions is going to conflict with that
+future AI, as there would be a mismash of automatic and declared static
+functions, and probably conflicts in some cases. Automatic static functions
+is a dead-end that would pretty much prevent any further changes to static
+processing.
+
+***************************************************************
+
+From: Tucker Taft
+Sent: Monday, October  9, 2017  8:45 PM
+
+>> Right.  But being *more* restrictive than absolutely necessary is our
+>> usual approach.  By requiring static expression functions to be
+>> defined where they are declared, we are keeping this AI simpler, and
+>> allowing ourselves to relax the restrictions later.
+>
+> Such a future AI would have to have a way (almost certainly an aspect)
+> to mark completions that are static functions. (A "generalization"
+> proposal that doesn't support private types is not really fixing
+> anything, IMHO.) An AI that has some sort of automatic static
+> functions is going to conflict with that future AI, as there would be
+> a mismash of automatic and declared static functions, and probably
+> conflicts in some cases. Automatic static functions is a dead-end that
+> would pretty much prevent any further changes to static processing.
+
+I could see adding an aspect to claim that something is a static function,
+and the compiler would check to be sure the expression then and there.  We
+could provide a configuration pragma some day to make it automatic, I suppose.
+
+But I still don't get how you can complete a static function in a private part
+or a body, if it is going to be static outside the package as well.  Because
+the *values* returned by the function can really matter to the caller, as they
+determine legality, and in some weird cases, can even determine the type (e.g.
+A'First(N) where "N" is a static expression function).
+
+Are you proposing that inside the package the function can be static, but not
+outside?  I suppose I could see some value in that.  I think that is how
+deferred constants work.  But I was getting the impression you wanted the
+"I_Am_Static" aspect on the visible declaration of the function, but not
+provide the body there as well.  That is what I don't understand...
+
+***************************************************************
+
+From: Randy Brukardt
+Sent: Monday, October  9, 2017  9:21 PM
+
+...
+> But I still don't get how you can complete a static function in a
+> private part or a body, if it is going to be static outside the
+> package as well.  Because the *values* returned by the function can
+> really matter to the caller, as they determine legality, and in some
+> weird cases, can even determine the type (e.g. A'First(N) where "N" is
+> a static expression function).
+
+I don't get this obsession with values. The first thing an Ada programmer
+learns is to use names rather than literals. And I have to assume the desire
+to use expression functions in static expressions is to get more abstraction
+into the expression.
+
+Yes, the value can determine legality. But so what? If the function implements
+a sensible, well-documented abstraction, it will work fine without worrying
+about the exact value returned. If it doesn't, well, we can't legislate
+perfection. I doubt very much that you care about the values of expressions in
+your program unless the compiler rejects them. That certainly would be the
+case here.
+
+> But I was getting the impression you wanted the "I_Am_Static"
+> aspect on the visible declaration of the function, but not provide the
+> body there as well.  That is what I don't understand...
+
+What about "abstraction" do you not understand?? Why you think these functions
+are somehow different than any other function ever written is what I don't
+understand. Any function someone writes might return a value other than one
+expected. Whether that makes the program illegal or just raises an exception
+doesn't change the response to it much. The programmer then has to look at the
+function body to see why an incorrect value was returned -- but that's the
+only time that one would look at the function body.
+
+If static expression functions aren't going to be used to provide abstraction,
+what else could they possibly be good for?? As I previously said, if they
+don't provide abstraction, then they aren't providing anything at all, and we
+should simply forget this idea.
+
+***************************************************************
```

Questions? Ask the ACAA Technical Agent