CVS difference for ai12s/ai12-0064-2.txt

Differences between 1.6 and version 1.7
Log of other versions for file ai12s/ai12-0064-2.txt

--- ai12s/ai12-0064-2.txt	2016/11/15 04:05:01	1.6
+++ ai12s/ai12-0064-2.txt	2016/12/22 03:29:18	1.7
@@ -107,7 +107,7 @@
        The Nonblocking aspect may be specified for all entities for
        which it is defined, except for protected operations and
        task entries. If directly specified, the aspect_definition shall
-       be a static expression. 
+       be a static expression.
 
        For a generic instantiation, the aspect is determined by the setting
        for the generic unit[Redundant, re-evaluated based on the actual
@@ -138,7 +138,7 @@
        formal subprogram, formal object, or (formal) access-to-subprogram
        type, the aspect is determined by the setting for the innermost
        program unit enclosing the entity.
-       
+
        If not specified for a library unit, the default is True if the
        library unit is declared pure and is not a generic unit, and
        False otherwise.
@@ -198,26 +198,26 @@
          allows a strict subset of the operations allowed in allows blocking
          subprograms, so calling such a subprogram as if it allows blocking
          -- as is necessary in a dispatching call -- is harmless.)
-       
+
        In a generic instantiation:
-       
+
         * the actual subprogram corresponding to a nonblocking formal
           subprogram shall be nonblocking (an actual that is an entry is
-          not permitted in this case); 
-        
+          not permitted in this case);
+
         * the actual type corresponding to a nonblocking formal
-          access-to-subprogram type shall be nonblocking; 
-        
+          access-to-subprogram type shall be nonblocking;
+
         * the actual object corresponding to a formal object of a
           nonblocking access-to-subprogram type shall be of a nonblocking
-          access-to-subprogram type; 
-          
+          access-to-subprogram type;
+
         * the actual instance corresponding to a nonblocking formal package
           shall be nonblocking.
-       
+
        In addition to the places where Legality Rules normally apply
        (see 12.3), the above rules apply also in the private part of an
-       instance of a generic unit.      
+       instance of a generic unit.
 
        AARM Ramification: For a generic formal parameter to be nonblocking
        (thus, for these rules to apply), either it or some enclosing
@@ -228,8 +228,8 @@
        such a case, these rules do apply in the instance of the specification
        of the generic unit (the normal re-checking is needed). For instance,
        the body of an expression function might make a prohibited call.
-            
-For a prefix S that denotes a subprogram (including a formal subprogram): 
+
+For a prefix S that denotes a subprogram (including a formal subprogram):
 
 S'Nonblocking
        Denotes whether subprogram S is considered nonblocking; the value
@@ -262,7 +262,7 @@
          of the nonblocking aspect of the actual subprogram, even if referenced
          through the name of the formal.
 
-For a prefix P that denotes a package (including a formal package): 
+For a prefix P that denotes a package (including a formal package):
 
 P'Nonblocking
        Denotes whether package P is considered nonblocking; the value
@@ -276,7 +276,7 @@
        Nonblocking aspect of P.
 
 For a prefix S that denotes an access-to-subprogram subtype (including formal
-access-to-subprogram subtypes): 
+access-to-subprogram subtypes):
 
 S'Nonblocking
        Denotes whether a subprogram designated by a value of type S is
@@ -289,13 +289,13 @@
 identified as needing a change (it's really broken, having nothing specifically
 to do with this AI).]
 
-The following are defined to be *potentially blocking* operations: 
+The following are defined to be *potentially blocking* operations:
 
   AARM Reason: The primary purpose of these rules is to define what operations
   are not allowed in a protected operation (blocking is not allowed). Some of
   these operations are not directly blocking. However, they are still treated
   as potentially blocking, because allowing them in a protected action might
-  impose an undesirable implementation burden. 
+  impose an undesirable implementation burden.
 
   * a select_statement;
   * an accept_statement;
@@ -305,12 +305,12 @@
   * an abort_statement;
   * task creation or activation;
   * an external call on a protected subprogram (or an external requeue) with
-    the same target object as that of the protected action; 
+    the same target object as that of the protected action;
 
   AARM Reason: This is really a deadlocking call, rather than a blocking call,
-  but we include it in this list for simplicity. 
+  but we include it in this list for simplicity.
 
-  * a call on a subprogram whose body contains a potentially blocking operation. 
+  * a call on a subprogram whose body contains a potentially blocking operation.
 
   AARM Reason: This allows an implementation to check and raise Program_Error as
   soon as a subprogram is called, rather than waiting to find out whether it
@@ -346,7 +346,7 @@
 order to reject most attempts to use potentially blocking operations within
 the protected unit (see 9.5). The pragma Detect_Blocking may be used to
 ensure that any remaining executions of potentially blocking operations
-during a protected action raise Program_Error. See H.5. 
+during a protected action raise Program_Error. See H.5.
 
   AARM Discussion: The deadlock case cannot be detected at compile-time,
   so pragma Detect_Blocking is needed to give it consistent behavior.
@@ -376,7 +376,7 @@
 
 Add after 4.6(24.21/4): [Type conversion Legality Rules for access-to-subprogram types]
 
-  * If the target type is nonblocking, the operand type shall be nonblocking. 
+  * If the target type is nonblocking, the operand type shall be nonblocking.
 
 Add after 4.9(8):
 
@@ -426,7 +426,7 @@
   manipulate files (implicitly or explicitly) are potentially blocking. Other
   potentially blocking subprograms are identified where they are defined. When
   not specified as potentially blocking, a language-defined subprogram is
-  nonblocking. 
+  nonblocking.
 
 Non-generic units that are pure are automatically nonblocking as specified in
 9.5 (these are noted below). Other units should explicitly have Nonblocking
@@ -672,7 +672,7 @@
 other declared pure library units. For pure generic units we leave the
 default at False for compatibility reasons, because these might have
 existing instances where an actual subprogram (or access-to-subprogram
-type) is potentially blocking. 
+type) is potentially blocking.
 
 We did not specify that protected subprograms are by default
 Nonblocking=>True, since that would be incompatible, as they then could
@@ -765,7 +765,7 @@
 
 In contrast, this proposal puts all of the burden on the implementer of a
 package (where it should be) and none on the user of the package. Alternative
-1 is definitely easier for the implementer of a package, and harder for a 
+1 is definitely easier for the implementer of a package, and harder for a
 user.
 
 Container usage examples:
@@ -807,7 +807,7 @@
     package My_Hashed_Map is new
        Ada.Containers.Hashed_Map (Label, Element, Hash, "=");
 
-is now illegal, as Hash has Nonblocking = False, and that fails to match the 
+is now illegal, as Hash has Nonblocking = False, and that fails to match the
 default for the formal parameter Hash (which is Nonblocking => True). Thus the
 user has to change their code and add Nonblocking => True to Hash or add
 Nonblocking => False to the instance My_Hashed_Map.
@@ -849,7 +849,7 @@
 
 !example
 
-  package Ada.Text_IO 
+  package Ada.Text_IO
     with Nonblocking => False is
    ...
     generic
@@ -866,12 +866,12 @@
                     Item : out Enum;
                     Last : out Positive)
         with Nonblocking => True;   --  explicitly Nonblocking => True
-        
+
       procedure Put(To   : out String;
                     Item : in  Enum;
                     Set  : in  Type_Set := Default_Setting)
         with Nonblocking => True;   --  explicitly Nonblocking => True
-        
+
     end Enumeration_IO
    ...
   end Ada.Text_IO;
@@ -969,6 +969,374 @@
 will steal the notion of an attribute of generic formals to specify more
 precisely the Global aspect for generic code, as there is a very similar
 problem there, and a similar solution seems appropriate.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Thursday, October 20, 2016  8:22 PM
+
+In private mail, I wrote:
+
+> Language design principle:
+>   If an expression in a generic is static, then the
+>   corresponding expression in an instance must also
+>   be static and must have the same value.
+
+Note that I'm not quoting this LDP from the RM or anywhere else. Randy and I had
+a discussion of how violating this principle leads to pestilence, famine, and
+other bad things. This discussion can be repeated if anyone is interested.
+
+>
+> Which brings us to the Nonblocking attribute as described in
+> alternative 2, version 1.5 of ai12-0064 (I know we just discussed this
+> AI in Pittsburgh, but I don't recall any updates that are relevant to
+> today's question).
+>
+> We've got:
+>
+>   For a prefix S that denotes a subprogram (including a formal
+>   subprogram):
+>
+>      S'Nonblocking
+>        ...; the value
+>        of this attribute ...is always static ...
+>
+>      If S denotes a formal subprogram of a generic unit G, the value of
+>      S'Nonblocking is True within the body of G or within the body of a
+>      generic unit declared within the declarative region of G, and False
+>      otherwise.
+>
+>     ...
+>
+>     In an instance, S'Nonblocking returns the value
+>     of the nonblocking aspect of the actual subprogram, even if
+>     referenced through the name of the formal.
+>
+> I think we have a problem here with a violation of the aforementioned
+> language design principle.
+
+Do folks agree that there is a problem here? I think this means that if the
+Nonblocking attribute of a generic formal subprogram is static, then the
+corresponding actual parameter must have a matching attribute value. There are
+several possible solutions which satisfy this but they each have drawbacks and
+would need to be discussed.
+
+For example, the Nonblocking attribute of a formal subprogram could be nonstatic
+and then an approach based on post-compilation rules (which could be checked at
+compile time by implementations which macro-expand instantiations) might work if
+combined with an idea Randy suggested, an almost-static expression which is
+non-static in a generic but will be static in any instance.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, October 20, 2016  8:39 PM
+
+>> Language design principle:
+>>   If an expression in a generic is static, then the
+>>   corresponding expression in an instance must also
+>>   be static and must have the same value.
+>>
+>
+> Note that I'm not quoting this LDP from the RM or anywhere else.
+> Randy and I had a discussion of how violating this principle leads to
+> pestilence, famine, and other bad things.
+> This discussion can be repeated if anyone is interested.
+
+I'd be somewhat interested, though I can imagine some weirdness if you capture
+the value of the attribute.  I think we want to eliminate the notion it is
+"always static."  We almost never say that sort of thing, and I think your
+principle about generics makes that unwise.  I think more frequently we talk
+about assuming the "best" in the generic spec (and rechecking in the instance)
+while assuming the worst in the generic body.  I suspect that that same approach
+can work here.
+
+>> ... We've got:
+>>
+>>   For a prefix S that denotes a subprogram (including a formal
+>>   subprogram):
+>>
+>>      S'Nonblocking
+>>        ...; the value
+>>        of this attribute ...is always static ...
+>>
+>>      If S denotes a formal subprogram of a generic unit G, the value of
+>>      S'Nonblocking is True within the body of G or within the body of a
+>>      generic unit declared within the declarative region of G, and False
+>>      otherwise.
+>>
+>>     ...
+>>
+>>     In an instance, S'Nonblocking returns the value
+>>     of the nonblocking aspect of the actual subprogram, even if
+>>     referenced through the name of the formal.
+>>
+>> I think we have a problem here with a violation of the aforementioned
+>> language design principle.
+>
+> Do folks agree that there is a problem here?
+
+Yes, saying this is "static" in a generic seems unwise.  I would rather use the
+"assume the best" and "assume the worst" approach.
+
+> For example, the Nonblocking attribute of a formal subprogram could be
+> nonstatic and then an approach based on post-compilation rules (which
+> could be checked at compile time by implementations which macro-expand
+> instantiations) might work if combined with an idea Randy suggested,
+> an almost-static expression which is non-static in a generic but will
+> be static in any instance.
+
+I think this is basically accomplishing something very similar to the assume the
+best/worst approach.  Of course when you say "any instance" you mean any
+instance that is not itself nested within a generic.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, October 21, 2016  12:18 PM
+
+...
+> > For example, the Nonblocking attribute of a formal subprogram could
+> > be nonstatic and then an approach based on post-compilation rules
+> > (which could be checked at compile time by implementations which
+> > macro-expand
+> > instantiations) might work if combined with an idea Randy suggested,
+> > an almost-static expression which is non-static in a generic but
+> > will be static in any instance.
+>
+> I think this is basically accomplishing something very similar to the
+> assume the best/worst approach.  Of course when you say "any instance"
+> you mean any instance that is not itself nested within a generic.
+
+That's (assume-the-worst/assume-the-best) is what the current rules are intended
+to accomplish. We essentially assume-the-worst about the value of the attribute
+in a generic body.
+
+What other way could work??
+
+Steve completely ignored our lengthy e-mail discussion in this note, forcing me
+to reproduce the entire thing here (and wasting another 30 minutes).
+
+In particular, he ignored a far more important (in my view) Language Design
+Principle (LDP):
+
+   If the value of an expression is needed to determine the result of a Legality
+   Rule, the expression shall be static.
+
+(Again, I don't think this is ever expressed in the AARM, but it should be
+pretty obvious.)
+
+Since the entire point of attribute Nonblocking is to use it in aspect
+Nonblocking, which controls Legality Rules, this LDP also applies.
+
+Clearly one of these LDPs has to be extensively modified in order to make this
+work.
+
+Also note that it is critical that Nonblocking attributes can be combined in
+expressions for the aspect Nonblocking. (Usually with "and", but I'd hate to
+limit things that way.) They also need to be able to be combined with other
+static expressions (such as a global flag).
+
+Specifically, we need to know what rules to enforce inside of generics for cases
+like:
+
+      procedure Foo (...)
+         with Nonblocking => Bar'Nonblocking and Glarch'Nonblocking and
+                             Some_Global_Nonblocking_Setting;
+
+The only solutions I see are far too heavy:
+
+The best I can do is to define something akin to a predicate-static expression
+(which I jokingly called a
+Steve_Baird_not_quite_memorial_and_not_quite_static_expression), and then such
+an expression would be allowed (by fiat) in aspect Nonblocking. LDP #2 would be
+modified to include the new kind of expression. That's awfully heavy. (*)
+
+The alternative of some sort of assume-the-worst fiat for a specified aspect
+Nonblocking and dropping the requirement for the expression to be static doesn't
+really work: it doesn't make sense if the expression is statically False (and
+the expression could be complicated and involve attributes Nonblocking from
+nongeneric units), and moreover we'd still have to somehow prevent
+       procedure Foo with Nonblocking => Some_Function(42);
+Once you've handled those issues, you're pretty much back to the other solution
+(just with more wording).
+
+So as far as I can tell, this kills Nonblocking unless some other solution can
+be found.
+
+(*) Here's the actual joke wording that I proposed:
+
+   A Steve_Baird_not_quite_memorial_and_not_quite_static_expression is
+      * A non-static Nonblocking attribute (that is, one given inside of a
+	generic that depends on a formal parameter); or
+      * A static expression; or
+      * A combination of two
+        Steve_Baird_not_quite_memorial_and_not_quite_static_expressions with a
+	logical binary operator; or
+      * The "not" operator applied to a
+	Steve_Baird_not_quite_memorial_and_not_quite_static_expression.
+
+We'd also have to define precisely which Nonblocking attributes are non-static,
+both here and in 4.9. (That alone will take a large number of words, because of
+the headaches of generic child units as well as nested generics.)
+
+We can get away with this little of a definition because we know that
+Nonblocking has type Boolean. (A complete definition would also include
+relational operators, but as they seem useless for type Boolean, I left them
+out.)
+
+There would be some value to a more general
+compile-time-known-but-not-static-expression (for 'Size of records, for
+instance), but that would be almost as much work to define as static expressions
+themselves.
+
+We'd have to come up with a better term.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, October 21, 2016  2:20 PM
+
+> ...
+>>> For example, the Nonblocking attribute of a formal subprogram could
+>>> be nonstatic and then an approach based on post-compilation rules
+>>> (which could be checked at compile time by implementations which
+>>> macro-expand
+>>> instantiations) might work if combined with an idea Randy suggested,
+>>> an almost-static expression which is non-static in a generic but
+>>> will be static in any instance.
+>>
+>> I think this is basically accomplishing something very similar to the
+>> assume the best/worst approach.  Of course when you say "any
+>> instance" you mean any instance that is not itself nested within a
+>> generic.
+>
+> That's (assume-the-worst/assume-the-best) is what the current rules
+> are intended to accomplish. We essentially assume-the-worst about the
+> value of the attribute in a generic body.
+>
+> What other way could work??
+
+I think making this static is unnecessary.  We have other legality rules that
+depend on the best case or worst case, without requiring the value to be static.
+
+> Steve completely ignored our lengthy e-mail discussion in this note,
+> forcing me to reproduce the entire thing here (and wasting another 30 minutes).
+>
+> In particular, he ignored a far more important (in my view) Language
+> Design Principle (LDP):
+>
+>    If the value of an expression is needed to determine the result of
+> a Legality Rule, the expression shall be static.
+>
+> (Again, I don't think this is ever expressed in the AARM, but it
+> should be pretty obvious.)
+
+I guess this is where I disagree.  We can say that something is illegal if the
+value *might* possibly be a particular value at run-time.  The *bounds* of what
+it might be needed to be known at compile time, but the actual value itself
+doesn't need to be static. We have a number of rules which are based on "known
+to be ..." sorts of things.
+
+> Since the entire point of attribute Nonblocking is to use it in aspect
+> Nonblocking, which controls Legality Rules, this LDP also applies.
+
+But it could apply only as a worst case or a best case, rather than by saying it
+is in fact static.
+
+> ...  moreover we'd still have to somehow prevent
+>        procedure Foo with Nonblocking => Some_Function(42); Once
+> you've handled those issues, you're pretty much back to the other
+> solution (just with more wording).
+
+I suspect we will end up going the same route as predicate static (as you
+mentioned), saying effectively that it must be an expression composed only of
+static subexpressions and 'Nonblocking attribute references.
+
+> So as far as I can tell, this kills Nonblocking unless some other
+> solution can be found.
+
+I don't see this as a "terminal" disease.  Perhaps just a bit of the LDP "flu."
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, October 21, 2016  2:44 PM
+
+...
+> > In particular, he ignored a far more important (in my view) Language
+> > Design Principle (LDP):
+> >
+> >    If the value of an expression is needed to determine the result
+> > of a Legality Rule, the expression shall be static.
+> >
+> > (Again, I don't think this is ever expressed in the AARM, but it
+> > should be pretty obvious.)
+>
+> I guess this is where I disagree.  We can say that something is
+> illegal if the value
+> *might* possibly be a particular value at run-time.  The
+> *bounds* of what it might be needed to be known at compile time, but
+> the actual value itself doesn't need to be static.
+>   We have a number of rules which are based on "known to be ..." sorts
+> of things.
+
+Sure, but none of those rules are based on the *value* of an expression (they're
+all other sorts of properties).
+
+> > Since the entire point of attribute Nonblocking is to use it in
+> > aspect Nonblocking, which controls Legality Rules, this LDP also applies.
+>
+> But it could apply only as a worst case or a best case, rather than by
+> saying it is in fact static.
+
+Surely; but that is just modifying the LDP to say "static or <new term
+here>". It doesn't invalidate the LDP in any way.
+
+> > ...  moreover we'd still have to somehow prevent
+> >        procedure Foo with Nonblocking => Some_Function(42); Once
+> > you've handled those issues, you're pretty much back to the other
+> > solution (just with more wording).
+>
+> I suspect we will end up going the same route as predicate static (as
+> you mentioned), saying effectively that it must be an expression
+> composed only of static subexpressions and 'Nonblocking attribute
+> references.
+
+Unless someone has a radical solution that doesn't cause other problems, it
+seems like the only sensible route.
+
+So, any ideas for the term to use?? I'll need something for the write-up, and
+"Steve Baird not quite memorial pseudo-static expression" probably doesn't work
+for most. :-)
+
+I suppose if we are going to use a one-time use term, we could copy the form of
+the "predicate-static" term and use "nonblocking-static". Other ideas?
+
+> > So as far as I can tell, this kills Nonblocking unless some other
+> > solution can be found.
+>
+> I don't see this as a "terminal" disease.  Perhaps just a bit of the
+> LDP "flu."
+
+It going to add quite a bit of wording to a concept that already has altogether
+too much wording (and also I've been requested to try to figure out how to make
+it work for record equality, a topic that I punted on because it appeared so
+hard - that's also going to add a lot of wording).
+
+But I suppose it is always darkest before the dawn. (I just wonder if the sun is
+actually going to come up.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Friday, October 21, 2016  3:28 PM
+
+> ... I suppose if we are going to use a one-time use term, we could
+> copy the form of the "predicate-static" term and use "nonblocking-static".
+> Other ideas?
+
+Yes, nonblocking-static is probably where we will end up.
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent