Version 1.1 of ai12s/ai12-0292-1.txt

Unformatted version of ai12s/ai12-0292-1.txt version 1.1
Other versions for file ai12s/ai12-0292-1.txt

!standard 5.5.3(9/5)          18-10-11 AI12-0292-1/01
!standard 5.5.3(13/5)
!standard 8.5.4(11)
!standard 9.10(14)
!class Amendment 18-10-11
!status work item 18-10-11
!status received 18-07-26
!priority Low
!difficulty Easy
!subject Various cleanups for Ada 2020
!summary
Various minor issues are corrected:
(1) Note 8.5.4(11) is deleted.
(2) 9.10(14) is reworded to use the term "exclusive protected operation" in order to include the effect of aspect Exclusive_Functions.
(3) The middle sentence of 5.5.3(9/5) is moved to be a Legality Rule.
!problem
Various minor issues, mostly caused about other Amendment AIs, are repaired.
(1) Note 8.5.4(11) is a lie. Ada 2005 allows entries renamed as procedures to be used in conditional and time entry calls, and in asynchronous selects.
(2) 9.10(14) does not take into account aspect Exclusive_Functions. This could matter if the functions are "protecting" some external object as in the case of the tampering data for Ada.Containers.
(3) The middle sentence of 5.5.3(9/5) (a Name Resolution Rule) is a Legality Rule for normal calls. This means that some complex overloading can be resolved. For instance:
procedure P (PP : access procedure (C : Cursor); F : Float := 3.14);
procedure P (PP : access procedure (C : Cursor); I : Integer := 12) is abstract;
for (C : Cursor) of P(<>) loop -- Legal? (No.)
A regular procedure call on P would not be legal:
P (Some_Proc'access); -- Illegal (ambiguous).
!proposal
(See Wording.)
!wording
Modify 5.5.3(9/5): [From AI12-0189-1]
The name or prefix given in an iterator_procedure_call shall resolve to denote a callable entity C that is a procedure, or an entry renamed as (viewed as) a procedure. [The name or prefix shall not resolve to denote an abstract subprogram unless it is also a dispatching subprogram. ]When there is an iterator_actual_parameter_part, the prefix can be an implicit_dereference of an access-to-subprogram value.
Add after 5.5.3(13/5): [From AI12-0189-1]
If the name or prefix given in an iterator_procedure_call denotes an abstract subprogram, the subprogram shall be a dispatching subprogram.
Delete 8.5.4(11).
Modify 9.10(14):
Both actions occur as part of protected actions on the same protected object, and at {least}[most] one of the actions is part of a call on {an exclusive protected operation}[a protected function] of the protected object.
!discussion
(1) The only part of 8.5.4(11) that remains true is the part about the Count attribute; that seems too obscure to warrant a Note.
(2) Since the definition of aspect Exclusive_Functions in the Corrigendum introduced the term "exclusive protected operation", we reword to use that term rather than duplicating definitions here.
(3) We generally don't want resolution to be too "smart", as that makes the meaning confusing for the reader. And we also want the rules to work similarly to the way explicit code would work.
!ASIS
No changes needed.
!ACATS test
(1) As this is not normative anyway, no tests are needed.
(2) Any Exclusive_Functions = True C-Test will implicitly test correct
implementation of this rule, but it's impractical to construct a test that would fail even when the implementation is wrong (as timing and ordering would be critical). So we conclude no test is needed.
(3) A B-test like the example in the !problem could be constructed, but that
would have low value.
!appendix

From: Randy Brukardt
Sent: Thursday, July 26, 2018  7:45 PM

In looking at subprogram renames, I came across note 8.5.4(11):

14  Calls with the new name of a renamed entry are procedure_call_statements 
and are not allowed at places where the syntax requires an 
entry_call_statement in conditional_ and timed_entry_calls, nor in an 
asynchronous_select; similarly, the Count attribute is not available for the 
new name.

The problem is that the bulk of this isn't true for Ada 2005 not to mention 
later versions of the language. For instance, 9.7.2 allows a timed entry call
to use a procedure_call_statement, and there is a Legality Rule which requires
that to be a renames of an entry (or various interface things). So this is 
specifically allowed by the rules.

So far as I can tell, only the Count attribute case remains true. That hardly
seems worth a note, so I recommend deleting this note.

Thoughts?

****************************************************************

From: Gary Dismukes
Sent: Thursday, July 26, 2018  8:35 PM

I say go for deletion.

****************************************************************

From: Tucker Taft
Sent: Sunday, July 29, 2018  7:38 AM

Agreed.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, September 4, 2018  11:00 PM

Having just finished added AI12-0119-1, I was checking AARM notes in 9.10 when
I started wondering about all of the bullets 9.10(3-10). Specifically, the 
introductory text to this list of bullets in 9.10(2) was all changed from
"task" to "logical thread of control".

Most of these bullets contain "task" in the wording. Upon closer inspection, 
most of them are about task-specific operations like activation, so no change
is needed. However the first bullet seems like it might be a problem:

  * If A1 and A2 are part of the execution of the same task, and the language
    rules require A1 to be performed before A2;

It seems to me that we want this to apply to logical threads of control, and 
not just tasks. Otherwise, we would have no reason to treat two actions within
the same logical thread of control to be sequential (as 9.10(13) claims is 
true). I was going to just change the text as an editorial review...but then I
started wondering if we really need this rule about tasks as well.

Specifically, this rule as currently written says that an action that occurs 
inside of a parallel construct (possibly in different threads) is still 
sequential with actions that follow the parallel construct. If we only talked
about logical threads of control, then we'd have no reason to make such an 
assumption (no signalling would happen).

I'm at the limit of my knowledge here -- in particular, it's not clear to me 
why we needed both 9.10(3) and 9.10(13) in previous Ada. (If we didn't, then 
we don't need a new version of 9.10(3), either. But these rules were very 
carefully constructed, and unlike other parts of the language have hardly been
touched in the intervening 23+ years.)

So, is there a problem here? Do we need to pull the AI to fix it (if a fix is
required)?

P.S. At a minimum, AARM notes 9.10(13.a) and (15.a) need to talk about 
"logical threads of control" rather than "tasks". I'm just making those
corrections.

P.P.S. In a case of what Steve calls "heat vision", I noted an unrelated issue 
in this clause. Specifically, I suspect that 9.10(14) is wrong, because it 
doesn't take into account aspect Exclusive_Functions. If the action is of 
two protected functions with Exclusive_Functions set, the actions should be
exclusive and thus should be sequential. (Since functions don't usually write
anything, that usually isn't an issue -- but it could be an issue for 
something like the tampering indicator of a container -- which was the 
motivating case for aspect Exclusive_Functions.) The wording should talk 
about "exclusive protected operations" (which is what 9.5.1 uses these
days) rather than "protected functions", something like:

Both actions occur as part of protected actions on the same protected object,
and at {least}[most] one of the actions is part of a call on {an exclusive 
protected operation}[a protected function] of the protected object. 

Thoughts on this aside?

****************************************************************

From: Tucker Taft
Sent: Thursday, September 6, 2018  6:38 AM

> Most of these bullets contain "task" in the wording. Upon closer 
> inspection, most of them are about task-specific operations like 
> activation, so no change is needed. However the first bullet seems like it 
> might be a problem:
> 
>  * If A1 and A2 are part of the execution of the same task, and the 
> language rules require A1 to be performed before A2;
> 
> It seems to me that we want this to apply to logical threads of 
> control, and not just tasks. Otherwise, we would have no reason to 
> treat two actions within the same logical thread of control to be 
> sequential (as 9.10(13) claims is true). I was going to just change 
> the text as an editorial review...but then I started wondering if we 
> really need this rule about tasks as well.

A given logical thread of control is always within a single task, so as 
written, it subsumes a similar statement using "logical thread of control."
In other words, if the language requires that A1 be performed before A2, then
A1 signals A2.  Even saying that they are part of the same task is probably
redundant.  So long as the language establishes an order, it really doesn't
matter whether they are part of the same logical thread of control, same task,
same program, ...
 
> Specifically, this rule as currently written says that an action that 
> occurs inside of a parallel construct (possibly in different threads) 
> is still sequential with actions that follow the parallel construct. 
> If we only talked about logical threads of control, then we'd have no 
> reason to make such an assumption (no signalling would happen).

Yes, that is a good reason to leave it as is.

> I'm at the limit of my knowledge here -- in particular, it's not clear 
> to me why we needed both 9.10(3) and 9.10(13) in previous Ada. (If we 
> didn't, then we don't need a new version of 9.10(3), either. But these 
> rules were very carefully constructed, and unlike other parts of the 
> language have hardly been touched in the intervening 23+ years.)

9.10(3) talks about the language specifying an order.  9.10(13) says merely 
that they are in the same logical thread of control, but no order is specified
by the language.  So they are quite different.  I believe they work together 
properly, even with one talking about tasks and the other talking about 
logical thread of control, because if two actions are part of the same logical
thread of control, they are clearly part of the same task.

> So, is there a problem here? Do we need to pull the AI to fix it (if a 
> fix is required)?

I don't believe so.

>P.S. At a minimum, AARM notes 9.10(13.a) and (15.a) need to talk about 
> "logical threads of control" rather than "tasks". I'm just making 
> those corrections.

Agreed
 
> P.P.S. In a case of what Steve calls "heat vision", I noted an 
> unrelated issue in this clause. Specifically, I suspect that 9.10(14) 
> is wrong, because it doesn't take into account aspect 
> Exclusive_Functions. If the action is of two protected functions with 
> Exclusive_Functions set, the actions should be exclusive and thus 
> should be sequential. (Since functions don't usually write anything, 
> that usually isn't an issue -- but it could be an issue for something 
> like the tampering indicator of a container -- which was the 
> motivating case for aspect Exclusive_Functions.) The wording should 
> talk about "exclusive protected operations" (which is what 9.5.1 uses 
> these days) rather than "protected functions", something like:
> 
> Both actions occur as part of protected actions on the same protected 
> object, and at {least}[most] one of the actions is part of a call on 
> {an exclusive protected operation}[a protected function] of the 
> protected object.
> 
> Thoughts on this aside?

Your suggested change makes sense to me.  Good catch!

****************************************************************

From: Randy Brukardt
Sent: Thursday, September 6, 2018  5:18 PM

...
> > I'm at the limit of my knowledge here -- in particular, it's not 
> > clear to me why we needed both 9.10(3) and 9.10(13) in previous Ada. 
> > (If we didn't, then we don't need a new version of 9.10(3), either. 
> > But these rules were very carefully constructed, and unlike other 
> > parts of the language have hardly been touched in the intervening 
> > 23+ years.)
> 
> 9.10(3) talks about the language specifying an order.  
> 9.10(13) says merely that they are in the same logical thread of 
> control, but no order is specified by the language.

9.10(13) never says anything about an order, specified by the language or 
otherwise. The AARM notes sort of imply that, but that seems irrelevant.

> So they are quite different.

Sure, but why did we need the first one (in the past)? Your response to 
this message implies that we did not (but do now, as discussed in the part
that I left out of this reply).

9.10(13) said that two actions in a single task (now LToC) are sequential 
regardless of what the language says about their order. (In particular, 
they are sequential if an order is specified as well as when it is 
unspecified. It's *always* the case.)

So far as I can tell, "signalling" is not used in any rules other than this
set of erroneous execution rules. So the rule about the language requiring 
an order is completely redundant with the rule for sequential actions.
(Obviously, if "signalling" is used in some other rules, that wouldn't be
true.)

OTOH, in the current wording, actions are unconditionally sequential only 
when they're in the same logical thread of control. The other wording says
that it also true if they're in different threads but the language requires
an order (as in the parallel loop followed by a call situation, where actions
taken by the loop have to occur before actions taken by the call).
So now we need both.

> I believe they work together
> properly, even with one talking about tasks and the other talking 
> about logical thread of control, because if two actions are part of 
> the same logical thread of control, they are clearly part of the same 
> task.

Yes, I think I agree *now*. I still don't know why we needed that in the past
-- but it's moot in any case (there's no importance to determining an answer).

****************************************************************

From: Tucker Taft
Sent: Thursday, September 6, 2018  10:28 PM

>9.10(13) never says anything about an order, specified by the language or
>otherwise. The AARM notes sort of imply that, but that seems irrelevant.

9.10(13) is saying that two actions are "sequential" any time they are in 
the same logical thread of control, *or* if one signals the other.  9.10(3)
gives us the "signaling" part, and 9.10(13) picks up the slack.

So they are quite different.

>Sure, but why did we need the first one (in the past)? Your response to this
>message implies that we did not (but do now, as discussed in the part that I
>left out of this reply).

I did not mean to imply that.  The same dichotomy existed between signaling 
and being sequential in Ada 95, and so both are needed.

>9.10(13) said that two actions in a single task (now LToC) are sequential
>regardless of what the language says about their order. (In particular, they
>are sequential if an order is specified as well as when it is unspecified.
>It's *always* the case.)

Right.

>So far as I can tell, "signalling" is not used in any rules other than this
>set of erroneous execution rules. So the rule about the language requiring
>an order is completely redundant with the rule for sequential actions.
>(Obviously, if "signalling" is used in some other rules, that wouldn't be
>true.)

The notion of signaling is fundamental to communicating using non-volatile 
shared variables, since without signaling, you can't be sure that a write to
a given shared variable occurs before a read of the same variable.  This is 
what 9.10(2/5) indicates:

...However, task interactions can be used to synchronize the actions of two or
more logical threads of control tasks to allow, for example, meaningful 
communication by the direct updating and reading of variables shared between
them the tasks.] The actions of two different logical threads of control tasks
are synchronized in this sense when an action of one task signals an action of
the other  ...

Note that signaling also shows up in an AARM note, in C.6(16.c/3):

16.c/3{AI05-0275-1} If for a shared variable X, a read of X occurs sequentially
after an update of X, then the read will return the updated value if X is 
volatile or atomic, but may or or may not return the updated value if X is
nonvolatile. For nonvolatile accesses, a signaling action is needed in order 
to share the updated value.

The relevant point is that if you want to communicate using non-volatile shared
variables, you need to establish a "signaling" relationship between the point 
where you write and the point where you read.  Otherwise there is no guarantee
that the read will see the effects of the write.  So signaling is needed when 
using non-volatile shared variables.  And even for volatile or atomic 
variables, signaling is needed to establish an order, even though the 
operations are, in the case of atomic, guaranteed to be sequential.

>OTOH, in the current wording, actions are unconditionally sequential only
>when they're in the same logical thread of control. The other wording says
>that it also true if they're in different threads but the language requires
>an order (as in the parallel loop followed by a call situation, where
>actions taken by the loop have to occur before actions taken by the call).
>So now we need both.

>>I believe they work together 
>>properly, even with one talking about tasks and the other 
>>talking about logical thread of control, because if two 
>>actions are part of the same logical thread of control, they 
>>are clearly part of the same task.

>Yes, I think I agree *now*. I still don't know why we needed that in the
>past -- but it's moot in any case (there's no importance to determining an
>answer).

See above.  Signaling is needed for meaningful communication using 
non-volatile shared variables.

****************************************************************

From: Randy Brukardt
Sent: Thursday, September 6, 2018  11:07 PM

>See above.  Signaling is needed for meaningful communication using 
>non-volatile shared variables.
 
But there is no consequence for violating signaling in the RM, so it's just 
extra words. The 'consequence' defined in the RM is erroneous execution, but
that happens when actions aren't sequential. Signaling is part of the 
definition of sequential, but it (so far as I can tell) has no other use. So 
we could have lived just fine only with the definition of sequential - it's 
hard to see why we need two very similar definitions.
 
I'd guess the only reason that signaling exists is so that it could be a 
recursive definition (we generally need a term to have a recursive 
definition), but it's hard for me to see why that's necessary and why we 
didn't just make sequential recursive instead of defining a separate term 
that turns this clause from difficult to understand to inscrutable. Probably
not worth trying to work out the consequences (as it would be an unnecessary
change in any case), but there still seems to be too much verbiage in this 
clause.
 
****************************************************************

From: Tucker Taft
Sent: Friday, September 7, 2018  7:20 AM

>But there is no consequence for violating signaling in the RM, so it's just 
>extra words. The 'consequence' defined in the RM is erroneous execution, but
>that happens when actions aren't sequential. Signaling is part of the 
>definition of sequential, but it (so far as I can tell) has no other use.
>So we could have lived just fine only with the definition of sequential -
>it's hard to see why we need two very similar definitions.

There is a serious language consequence, namely that you might get the wrong 
answer if you don't use some kind of signaling to ensure the "write" occurs 
before the "read."  Agreed there is no erroneousness for getting the wrong 
answer, but from a user point of view, the fundamental dynamic semantics are 
only meaningful if signaling is used between the write and the read.

>I'd guess the only reason that signaling exists is so that it could be a 
>recursive definition (we generally need a term to have a recursive 
>definition), but it's hard for me to see why that's necessary and why we
>didn't just make sequential recursive instead of defining a separate term
>that turns this clause from difficult to understand to inscrutable. Probably
>not worth trying to work out the consequences (as it would be an unnecessary
>change in any case), but there still seems to be too much verbiage in this 
>clause.

There is a critical difference between signaling and sequentiality.  Signaling 
is the way to establish an order between actions that occur in different tasks,
which is fundamental to communicating via shared data (atomic or otherwise).
Sequentiality merely means the two actions don't overlap, but there is no 
guarantee which happens first.  For example:

G : Integer := 33 with Atomic;

task body T1 is
begin
    G := 42;
    <action A1>
end;

task body T2 is
begin
    <action A2>
   Put_Line("G = " & G'Image);
end;

We need to be sure that action A1 signals action A2 if we expect the Put_Line 
in T2 to produce "G = 42".

****************************************************************

From: Randy Brukardt
Sent: Friday, September 7, 2018  6:03 PM

>There is a serious language consequence, namely that you might get the wrong 
>answer if you don't use some kind of signaling to ensure the "write" occurs 
>before the "read."  Agreed there is no erroneousness for getting the wrong 
>answer, but from a user point of view, the fundamental dynamic semantics are
>only meaningful if signaling is used between the write and the read. 
 
There's a large number of problems with this idea:
(1) It's not a "wrong" answer, it's one of a set of possible answers. When the
    language defines the order to be unspecified, that doesn't give license 
    for any answer! Only erroneousness does that.
(1A) AARM note 9.10(15.b) already notes that an unspecified order is not 
    necessarily a mistake.
(2) It's not the language definition's job to tell programmers how to get the 
    right answer. If we can do that cheaply, that's fine, but defining 
    unnecessary terms which complicate already complex area further is going 
    too far.
(3) Taking require sequential order into account is only one small face of 
    what's required to get the right answer. Why does not having an 
    unspecified order matter enough to be mentioned here, but other things 
    that are unspecified (for instance, how parameters are passed for most 
    composite types) or erroneous (for instance, dangling pointers) not rate?
    It would be nonsense if accessing an object from multiple threads suddenly
    had more order than accessing it from a single thread, so I don't see any 
    reason that anyone would expect something different. And certainly all of 
    the other ways that a sequential piece of code can go wrong are being 
    assumed here.
 
...
>We need to be sure that action A1 signals action A2 if we expect the Put_Line 
>in T2 to produce "G = 42".
 
Which is just extra words, yet again. (And ones that literally sound like 
nonsense, as nothing is going between the two actions when "signaling" 
happens; the term sounds like some sort of communication is required, but
that rarely is the case). These are two different threads, no POs in sight,
and thus signaling = sequential. If the write of G and the read of G are 
sequential, you are fine, and if they are not, you are not. What else could 
we possibly need?
 
As previously noted, we're not going to change this, regardless of how 
maddening the definitions are. So I don't suppose we really need to agree on
this (so long as we don't disagree on the ultimate meaning, and I think we're
OK there).

****************************************************************

From: Tucker Taft
Sent: Saturday, September 8, 2018  9:04 AM

>Which is just extra words, yet again. (And ones that literally sound like 
>nonsense, as nothing is going between the two actions when "signaling" 
>happens; the term sounds like some sort of communication is required, but
>that rarely is the case). These are two different threads, no POs in sight,
>and thus signaling = sequential.

I don't think you understood my example.  I meant that the user had to fill in
what were action A1 and action A2 such that A1 signals A2.  In the above, so 
far there is no signaling.  To provide signaling, A1 could be setting a value
in a protected object, while A2 waits for the value to be set.  Another would
be for T2 to be a subtask of T1, with the assignment to G happening before 
task T2 is created.  Or any other pair of actions such that A1 signals A2.

****************************************************************

From: Randy Brukardt
Sent: Sunday, September 9, 2018  12:19 AM

My point all along is that the concept of signaling is not really necessary,
and an example that gives the same effect whether you use "signaling" or
"sequentiality" to determine the result provides no information about 
whether I am right or wrong in that contention. Since most actions that
"signal" have no sort of interaction at all (they only "signal" because some
other actions that they are related to in some way signal), the term (which 
implies that some interaction has taken place by the actions in question) is
beyond confusing. It would have been better if it was called "frobbing" or 
some other nonsense with no English meaning. I find it much easier to 
understand what is going on by ignoring signaling altogether and only worrying
about sequentiality (which of course means in many cases determining whether 
signaling happens, but that just gets treated as a meaningless but necessary 
intermediate step -- the term itself is ignored).

****************************************************************

From: Tucker Taft
Sent: Sunday, September 9, 2018  9:19 AM

At this point I guess we should agree to disagree.  To me there is a 
fundamental difference between knowing two actions do not overlap, versus 
knowing that one precedes the other.  Nevertheless, we seem to agree that 
no further change is needed here.

****************************************************************

From: Randy Brukardt
Sent: Monday, September 24, 2018  12:19 AM

This AI has the following as paragraph 9 under Name Resolution Rules:

The name or prefix given in an iterator_procedure_call shall resolve to denote 
a callable entity C that is a procedure, or an entry renamed as (viewed as) a 
procedure. The name or prefix shall not resolve to denote an abstract 
subprogram unless it is also a dispatching subprogram. [When there is an 
iterator_actual_parameter_part, the prefix can be an implicit_dereference of 
an access-to-subprogram value.]

The middle sentence here strikes me as a Legality Rule. In particular, the 
similar rule for regular calls is a Legality Rule (3.9.3(7)).

Moreover, we don't want resolution to be too "smart". Requiring resolution to 
a procedure makes sense, so that functions and objects aren't considered.
And it's the same as a regular procedure call (6.3(8/2)). But I doubt we want 
to get more specific than that.

The rule as written would require something like the following to resolve 
(since all resolution rules are taken as a set):

     procedure P (PP : access procedure (C : Cursor); F : Float := 3.14);

     procedure P (PP : access procedure (C : Cursor); I : Integer := 12) is abstract;

     for (C : Cursor) of P(<>) loop -- ???

I'd hope that something like this is ambiguous, regardless of whether calling 
the second P is legal or not. Again, for a regular procedure call:

     P (Some_Proc'access);

this would be ambiguous.

I'd suggest that we move that sentence to after the existing Legality Rule 
(5.5.3(13/5)), and probably reword it a bit to be more like 3.9.3(7):

If the name or prefix given in an iterator_procedure_call denotes an abstract 
subprogram, the subprogram be a dispatching subprogram.

Or possibly:

If the name or prefix given in an iterator_procedure_call shall not denotes 
an abstract subprogram unless it is also a dispatching subprogram.

My preference would be to do this in a clean-up AI, as it's practically too 
late to change this AI before the meeting. (And I'd rather not reopen it and 
rehash all of the previous discussion because of a minor wording point.)

****************************************************************

From: Randy Brukardt
Sent: Tuesday, September 25, 2018  2:13 PM

Typos in proposed wording: 

...
> I'd suggest that we move that sentence to after the existing Legality 
> Rule (5.5.3(13/5)), and probably reword it a bit to be more like 
> 3.9.3(7):
> 
> If the name or prefix given in an iterator_procedure_call denotes an 
> abstract subprogram, the subprogram be a
shall be-----------------------------------------^
> dispatching subprogram.
> 
> Or possibly:
> 
> If the name or prefix given in an iterator_procedure_call shall not 
> denotes an abstract subprogram unless it is also a
denote------^
> dispatching subprogram.
> 
> My preference would be to do this in a clean-up AI, as it's 
> practically too late to change this AI before the meeting.
> (And I'd rather not reopen it and rehash all of the previous 
> discussion because of a minor wording point.)

****************************************************************

From: Tucker Taft
Sent: Tuesday, September 25, 2018  2:19 PM

Your proposal to treat this as part of a "cleanup" AI, modulo the typos 
you mentioned, seems fine.

****************************************************************

From: Jeff Cousins
Sent: Tuesday, September 25, 2018  4:21 PM

Ditto.  I have a slight preference for the first option as ‘shall be’ is more
positive and more common than ‘shall not’, but either is good.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, September 25, 2018  5:26 PM

In case anyone is on the fence, Steve privately sent me a note this morning 
(with those typos, I should have given him credit before) with in part the 
following comment on the change:

"The general idea that we want the informal equivalence rule for these loops 
to include equivalence with respect to name resolution sounds right to me."

...which seems like a better justification for the change than the way I 
described it.

****************************************************************


Questions? Ask the ACAA Technical Agent