CVS difference for ai12s/ai12-0079-1.txt

Differences between 1.14 and version 1.15
Log of other versions for file ai12s/ai12-0079-1.txt

--- ai12s/ai12-0079-1.txt	2018/01/27 04:54:50	1.14
+++ ai12s/ai12-0079-1.txt	2018/03/01 07:24:22	1.15
@@ -2117,7 +2117,7 @@
 ****************************************************************
 
 From: Randy Brukardt
-Sent: Thursday, Janaury 25, 2018  6:00 PM
+Sent: Thursday, January 25, 2018  6:00 PM
 
 ...
 > > I rather disagree; phone meetings are best for wordsmithing since it
@@ -2154,9 +2154,13 @@
 > can let me know what you feel you need to annotate the containers,
 > I'll try to finalize that part of the wording.
 
-I'm not completely sure at this stage, as I've never felt the proposal was solid enough to proceed. Obviously, the containers are generic, so all of the rules involving combinations and reflecting the Globals of the actuals in generic specs need to be fig
ured out in detail.
+I'm not completely sure at this stage, as I've never felt the proposal was
+solid enough to proceed. Obviously, the containers are generic, so all of the
+rules involving combinations and reflecting the Globals of the actuals in
+generic specs need to be figured out in detail.
 
-This is rather complex for Nonblocking (which is worked out), and Global is 10 times harder, so the lack of work in that area is concerning.
+This is rather complex for Nonblocking (which is worked out), and Global is 10
+times harder, so the lack of work in that area is concerning.
 
 > For me it just seemed like there was a general fine tuning needed, but
 > apparently you feel there are still some big issues, at least when it
@@ -2256,3 +2260,446 @@
 and AI12-0112-1 had better wait lest the Jan 15th rush not get processed.
 
 ****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, February 18, 2018  5:29 PM
+
+...
+>>I am willing to spend more time on 0079.  I did not realize 
+>>that the above was your concern.  Perhaps we can handle this 
+>>offline.  If you can let me know what you feel you need to 
+>>annotate the containers, I'll try to finalize that part of 
+>>the wording.
+>
+>I'm not completely sure at this stage, as I've never felt the proposal was
+>solid enough to proceed. Obviously, the containers are generic, so all of
+>the rules involving combinations and reflecting the Globals of the actuals
+>in generic specs need to be figured out in detail.
+>
+>This is rather complex for Nonblocking (which is worked out), and Global is
+>10 times harder, so the lack of work in that area is concerning.
+
+I am not sure what you mean here.  We have the 'Global attribute and permit 
+the use of "&" to combine global specifications.  What more do you think we 
+need?
+
+>>For me it just seemed like there was a general 
+>>fine tuning needed, but apparently you feel there are still 
+>>some big issues, at least when it comes to annotating the 
+>>libraries.  So if you can give me a clearer idea of what you 
+>>need, I'll focus on that.
+
+>The other issue for the libraries is clearly what to do about
+>implementation-defined "helper" packages. We surely have to allow
+>implementations to have such packages, and they might in some circumstances
+>have globals in them. It would seem nasty to ban that (other than in Pure
+>packages, of course). And we surely can't name any such packages in the
+>Standard!
+
+Private descendants are considered part of the package body from the point 
+of "Global => (in out => P private)".  Do we need more than that as a way to
+support "helper" packages?
+
+>There's also an issue that is not specific to Global, but matters a lot.
+>Since attribute prefixes have to be unambiguous without context, most of the
+>names of generic formals can't be directly used in an attribute. That means
+>that they have to be renamed to a unique name so that they can be used. For
+>instance, for Vectors:
+>
+>generic
+>  type Index_Type is range <>;
+>  type Element_Type is private;
+>  with function "=" (Left, Right : Element_Type) return Boolean is <>;
+>package Ada.Containers.Vectors 
+>  with Preelaborate, Remote_Types,
+>       Nonblocking => Equal_Element'Nonblocking,
+>       Global => Equal_Element'Global and <impl-def stuff??> and <the body of this package> is
+>
+>  function Equal_Element (Left, Right : Element_Type) return Boolean renames "=";
+>
+>  ...
+>
+>The aspects Nonblocking and Global give the default declaration of the
+>aspects for the contents, and we surely don't want to repeat them on all
+>(approx) 70 subprograms.
+>
+>However, we've never defined what the freezing point of a package
+>declaration is, so the place where these aspects are evaluated is not
+>well-defined. So I don't even know if this formulation is legal. And if it
+>isn't legal, is there any alternative that IS legal that doesn't require
+>repeating Nonblocking and Global aspects 70 times.
+
+Fine, but that seems to be a separate AI.  I think it is safe to assume that
+this can be fixed to work the way we want it to for Global and Nonblocking, 
+so this shouldn't interfere with you making progress.
+
+>The third issue is about the actual definition of "synchronized". The
+>purpose of this setting is to mark task-safe code that still uses global
+>variables. It's pretty clear that 100% elimination of data races is
+>impossible if any globals are involved (as soon as there is more than one
+>global, data locks are impossible to avoid with static rules). ...
+
+There are "data races" and "race conditions."  Frequently these are treated as 
+synonyms, but if there is a distinction, it is that "A := A + 1" does not
+involve a "data race" if A is atomic, but it is clearly a race condition.  I
+don't think we have a prayer of preventing these kinds of race conditions.
+Certainly a friendly compiler could recognize some of these simple patterns,
+and provide a warning, but I don't see that we can hope for much more than
+that.  Again, I think this is a separate AI, or simply out of scope for Ada
+standardization.
+
+So I don't find any of the above issues particularly relevant to AI12-0079 and 
+its use in annotating language-defined packages.  *However*, I do think we have
+a significant issue with respect to access types.  We really want a way to say 
+that the side-effects are limited to heap objects "reachable" from a given
+parameter.  Saying that a subprogram updates something designated by a given 
+access type is pretty useless.
+
+So I plan to spend some time thinking about this problem of access types,
+especially in the context of container-like packages that clearly use access
+types behind the scenes.  But I don't see that there is much more needed to 
+address the issues you identify above.  If you don't agree, please advise!
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, February 19, 2018  9:45 PM
+
+> I am not sure what you mean here.  We have the 'Global attribute and permit
+> the use of "&" to combine global specifications.  What more do you think we
+> need?
+
+The assume-the-best and assume-the-worst rules for using the 'Nonblocking
+attribute inside a generic turned out to be pretty complex in order to be
+usable. And those are just "on-off" type rules!
+
+I'd like to have at least some feeling that we can make the rules for 'Global
+attribute inside of a generic usable before using them everywhere and assuming
+that implementers can figure it out.
+
+I suppose this is more of a concern for the actual proposal rather that need
+in the spec of the containers. But if no one can write a legal body for the 
+containers, that would be bad...
+
+...
+>> The other issue for the libraries is clearly what to do about
+>> implementation-defined "helper" packages. We surely have to allow
+>> implementations to have such packages, and they might in some circumstances
+>> have globals in them. It would seem nasty to ban that (other than in Pure
+>> packages, of course). And we surely can't name any such packages in the
+>> Standard!
+		
+> Private descendants are considered part of the package body from the point
+> of "Global => (in out => P private)".  Do we need more than that as a way
+> to support "helper" packages?
+
+Traditionally, helper packages are in some implementation-defined subsystem.
+The obvious example is IO. In Janus/Ada, we have the helper package defined 
+as System.Basic_IO. All of the language-defined packages are defined in terms
+of it. (It has a bit of state to support Standard-in/Standard-out.) I believe
+GNAT has some such package in the GNAT subsystem.
+
+For containers, I suppose a global non-generic helper could be a private child
+of Ada.Containers. (There sadly isn't an Ada.IO subsystem.) But that
+*still* isn't a "private descendant" of the generic Ada.Containers.Vectors!
+And there is no way to have a non-generic private descendant of a generic
+package. [If I was going to use a helper at all, it would definitely be 
+non-generic.]
+
+I vaguely remember that one option discussed was just to punt and let
+implementers put anything that they wanted as additional dependencies into
+Global for impure packages. That would seem to work, especially if we allowed
+mentioning packages only referenced from a private with in Global aspects.
+(Putting "private" into the context clause would make it clear that the only
+reason for mentioning these packages is so that the dependencies can be
+visible for checks. I believe that we already allow adding "private withs"
+as those are semantically transparent for the purposes of the language-defined
+specification.)
+
+...	
+>> However, we've never defined what the freezing point of a package
+>> declaration is, so the place where these aspects are evaluated is not
+>> well-defined. So I don't even know if this formulation is legal. And if it
+>> isn't legal, is there any alternative that IS legal that doesn't require
+>> repeating Nonblocking and Global aspects 70 times.
+>		
+> Fine, but that seems to be a separate AI.  I think it is safe to assume
+> that this can be fixed to work the way we want it to for Global and
+> Nonblocking, so this shouldn't interfere with you making progress.
+
+The reassurance that it can be made to work is important, at least for my
+psyche. I don't want to do this overall and then have to start over because
+of a bad assumption at the start...
+
+>> The third issue is about the actual definition of "synchronized". The
+>> purpose of this setting is to mark task-safe code that still uses global
+>> variables. It's pretty clear that 100% elimination of data races is
+>> impossible if any globals are involved (as soon as there is more than one
+>> global, data locks are impossible to avoid with static rules). ...
+		
+> There are "data races" and "race conditions."  Frequently these are treated
+> as synonyms, but if there is a distinction, it is that "A := A + 1" does not
+> involve a "data race" if A is atomic, but it is clearly a race condition.
+
+This seems like hair-splitting. Either way it doesn't work, but only
+intermittently.
+
+> I don't think we have a prayer of preventing these kinds of race conditions.
+> Certainly a friendly compiler could recognize some of these simple patterns,
+> and provide a warning, but I don't see that we can hope for much more than
+> that.  Again, I think this is a separate AI, or simply out of scope for Ada
+> standardization.
+
+I don't see any good reason to allow writes to atomic objects to be considered
+safe unless they are writing a static value, or are using one of a atomic
+update operations that Bob doesn't think we need to define. ;-) Anything else
+is a guaranteed race condition, so why allow it in the first place? Most of
+these sorts of operations should be wrapped into protected objects in order to
+be clearly safe. (And even those can be abused, and probably there ought to be
+a check for dubious cases as when the same protected object occurs more than
+once in a single expression, but that's more like a warning.)
+
+Recall how I'd expect to use the parallelism features (because it's the way I
+do all of my Ada programming these days): add parallel to an appropriate loop
+and let the compiler tell me what needs to be changed. Ada compilers are ten 
+times better at finding issues than I would be -- the big problem I have with
+the current tasking model is that it leaves the programmer completely on your
+own. I realize that finding every problem statically is probably impractical,
+but I don't want to leave anything obvious get through. (If one remembers that
+one can only have a single global object in order to be safe, then a proper
+set of rules should make it hard to have any undetected problems in that case.
+More than one global object is a lost cause; I'd just ban parallelism in that
+case, but I don't know how to even do that. :-)
+
+> So I don't find any of the above issues particularly relevant to AI12-0079
+> and its use in annotating language-defined packages.  *However*, I do think
+> we have a significant issue with respect to access types.  We really want a
+> way to say that the side-effects are limited to heap objects "reachable"
+> from a given parameter.  Saying that a subprogram updates something designated
+> by a given access type is pretty useless.
+
+I don't think there is any other practical option. This just demonstrates why
+one should never use access types in visible interfaces. (I think I've been
+saying that for 20 years. ;-)
+
+> So I plan to spend some time thinking about this problem of access types,
+> especially in the context of container-like packages that clearly use
+> access types behind the scenes.  But I don't see that there is much more
+> needed to address the issues you identify above.  If you don't agree,
+> please advise!
+
+Luckily, we previously agreed to add reading operations that pass the
+container. (Which also allows sensible prefix notation using the container
+object for reading.) The preconditions then disallow any cases where we are
+talking about the implicit container. So I think we're OK reasoning just about
+cursor referencing something in the "current" container object,
+Which doesn't need to be mentioned in Global.
+
+The old reading operations are a lost cause, but that's OK: don't use them if
+you care about the Global reference. BTW, do we have an annotation for "any
+object of a type"? That's what those need (it's not designated by some access
+type, since there is no visible access definition, and I would be disgusted to
+have to declare such a type just for use in Global references).
+
+Not that I would mind if you have some better definition, I'm sure it would be
+useful somewhere.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, February 19, 2018  10:25 PM
+
+> I don't see any good reason to allow writes to atomic objects to be
+> considered safe unless they are writing a static value, or are using one of
+> a atomic update operations that Bob doesn't think we need to define. ;-) ...
+
+This is an interesting point of view, but I still think it is completely 
+unrelated to the Global annotation AI.  I still think this is more of a
+"warning" situation than an error.  I don't think we should be in the
+business of disallowing use of atomic variables to provide synchronization,
+but I could see a compiler warning you about certain uses.
+
+>>... *However*, I do think
+>> we have a significant issue with respect to access types.  We really
+>> want a way to say that the side-effects are limited to heap objects
+>> "reachable" from a given parameter.  Saying that a subprogram updates
+>> something designated by a given access type is pretty useless.
+>
+>I don't think there is any other practical option. This just demonstrates
+>why one should never use access types in visible interfaces. (I think I've
+>been saying that for 20 years. ;-)
+
+I am not talking about using access types in a visible interface, but rather
+trying to define what a given interface does in terms of its reading and
+writing of heap-resident data, in a way that it can be checked by the
+compiler.
+
+In any case, I have some new ideas how to do this, using a 'Reachable 
+attribute.  I'll write this up shortly.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, February 19, 2018  11:49 PM
+
+>> I don't see any good reason to allow writes to atomic objects to be
+>> considered safe unless they are writing a static value, or are using one of
+>> a atomic update operations that Bob doesn't think we need to define. ;-) ...
+>		
+> This is an interesting point of view, but I still think it is completely
+> unrelated to the Global annotation AI.  I still think this is more of a
+> "warning" situation than an error.  I don't think we should be in the
+> business of disallowing use of atomic variables to provide synchronization,
+> but I could see a compiler warning you about certain uses.
+
+We *should* be in the business of disallowing unsafe code by default (for the 
+purpose of parallel execution), and that is what Global does here.
+Anything should be fine in the Global => all case, because that doesn't
+promise any safety. Atomic variables are only usable for synchronization with
+xtreme care, and "extreme care" runs counter to the purpose of having safety 
+rules in the first place. (You can use any sort of global object with "extreme
+care", after all. :-)
+
+But I agree this should be a "suppressible error" (indeed, one could argue that
+all of the checks for a parallel loop, etc. should be suppressible). Of course,
+that would imply that Bob or someone decides to actually progress that AI...
+
+...
+> I am not talking about using access types in a visible interface, but rather
+> trying to define what a given interface does in terms of its reading and
+> writing of heap-resident data, in a way that it can be checked by the
+> compiler.
+
+OIC. You're worried that the static rules would pretty much have to disallow 
+doing anything heap-related in the body of a subprogram, since we don't know 
+that the heap objects "belong" to the parameter and won't be shared with other
+objects. (Such heap objects shouldn't appear in Global at all -- the part I
+was worrying about -- since they are of types that are likely private/body and
+designate types only defined in the private part or body, and as such
+mentioning them is nonsense.) Having to include the "heap" in Global in such a
+case would make almost everything Global => all, which isn't useful.
+
+> In any case, I have some new ideas how to do this, using a 'Reachable
+> attribute.  I'll write this up shortly.
+
+Sounds good. Hope it isn't too complicated.
+
+***************************************************************
+
+From: Tucker Taft
+Sent: Saturday, February 24, 2018  9:01 PM
+
+> ...
+> 
+> However, we've never defined what the freezing point of a package 
+> declaration is, so the place where these aspects are evaluated is not 
+> well-defined. So I don't even know if this formulation is legal. And 
+> if it isn't legal, is there any alternative that IS legal that doesn't 
+> require repeating Nonblocking and Global aspects 70 times.
+
+Below are two paragraphs I am planning to add to the Global aspect AI.  Do
+these address this issue adequately?
+
+----------
+
+Modify 13.1.1(11/3):
+
+  The usage names in an aspect_definition [Redundant: are not resolved
+  at the point of the associated declaration, but rather] are resolved
+  at the end of the immediately enclosing declaration list{, or in the
+  case of the declaration of a library unit, at the end of the visible
+  part of the entity}.
+  
+Modify 13.14(3/5):
+
+  The end of a declarative_part, protected_body, or a declaration of a
+  library package or generic library package, causes freezing of each
+  entity and profile declared within it{, as well as the entity itself
+  in the case of the declaration of a library unit}.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, February 26, 2018  9:34 PM
+
+> Below are two paragraphs I am planning to add to the Global aspect AI.  
+> Do these address this issue adequately?
+
+So long as they don't stomp on the rules for categorization aspects, we should
+be fine.
+ 
+> ----------
+> 
+> Modify 13.1.1(11/3):
+> 
+>   The usage names in an aspect_definition [Redundant: are not resolved
+>   at the point of the associated declaration, but rather] are resolved
+>   at the end of the immediately enclosing declaration list{, or in the
+>   case of the declaration of a library unit, at the end of the visible
+>   part of the entity}.
+
+
+Luckily, 13.1.1(32/4) is a "Notwithstanding" rule, so what we say for the 
+"normal" case doesn't matter. In particular, 13.1.1(32/4) says:
+
+Notwithstanding what this International Standard says elsewhere, the 
+expression of an aspect that can be specified by a library unit pragma is
+resolved and evaluated at the point where it occurs in the 
+aspect_specification[, rather than the first freezing point of the
+associated package].
+
+The redundant remark might be a bit confusing (depending on whether the above
+paragraph or the below paragraph is read), but it seems OK. Or we could change
+it to "rather than the end of the visible part of the entity".
+
+Humm: do library units that are subprograms or renames have a visible part??
+Humm part 2: the index points us to a sentence (in 8.2(5)) that is described
+as "redundant" for the definition of visible part. Anyway, that implies that
+a subprogram profile is the visible part; for a renames, it appears that
+there is no visible part. So, let's rephrase: does the visible part of a
+subprogram or rename have a well-defined end?
+   
+> Modify 13.14(3/5):
+> 
+>   The end of a declarative_part, protected_body, or a declaration of a
+>   library package or generic library package, causes freezing of each
+>   entity and profile declared within it{, as well as the entity itself
+>   in the case of the declaration of a library unit}.
+
+Looks OK to me.
+
+***************************************************************
+
+From: Tucker Taft
+Sent: Monday, February 26, 2018  10:28 PM
+
+> Humm: do library units that are subprograms or renames have a visible part??
+
+Yes they do.  Look in RM 8.2
+
+> Humm part 2: the index points us to a sentence (in 8.2(5)) that is 
+> described as "redundant" for the definition of visible part. Anyway, 
+> that implies that a subprogram profile is the visible part; for a 
+> renames, it appears that there is no visible part.
+
+The wording might not be precise in its use of "entity" vs. "declaration," but
+I think it is clear the intent that the profile in a subprogram renaming is
+the visible part.
+
+> So, let's rephrase: does the visible part of a subprogram or rename 
+> have a well-defined end?
+
+It seems like it ends at the end of the profile.  Where else would it end?
+
+>> Modify 13.14(3/5):
+>> 
+>>  The end of a declarative_part, protected_body, or a declaration of a  
+>> library package or generic library package, causes freezing of each  
+>> entity and profile declared within it{, as well as the entity itself  
+>> in the case of the declaration of a library unit}.
+> 
+> Looks OK to me.
+
+Good.
+
+***************************************************************

Questions? Ask the ACAA Technical Agent