Version 1.2 of ai05s/ai05-0220-1.txt

Unformatted version of ai05s/ai05-0220-1.txt version 1.2
Other versions for file ai05s/ai05-0220-1.txt

!standard 4.3.1(17)          10-08-04 AI05-0220-1/01
!class binding interpretation 10-06-13
!status work item 10-06-13
!status received 10-03-16
!priority Low
!difficulty Easy
!qualifier Clarification
!subject Definition of "needed component"
!summary
Staticness requirements clarified for record aggregate discriminants.
!question
Consider:
type Enum is (One, Two, Three); type Variant_Record (Disc : Enum) is record case Disc is when One => I : Integer; when Two => F : Float; when Three => null; end case; end record;
Variant_Part' (Disc => Function_Call(Param));
4.3.1(9) says that the components that are "needed" are determined by the "composite value"; that depends on the discriminant values.
The discriminant values can be determined at runtime; in this case the needed components are not known until runtime. But "needed" components participate in Legality Rules and clearly need to be known at compile-time.
4.3.1(17) attempts to require a static discriminant value, but it depends on the definition of "needed". Thus, one could argue that the aggregate above is legal if Function_Call returns Three. That is obviously nonsense, but exactly where is the line drawn? If we have:
type Variant_Record_2 (Disc : Enum) is record case Disc is when others => null; end case; end record; R : Variant_Record_2 := (Disc => Some_Function_Call);
In this case, there are no components in the variant part, so it hard to see how 4.3.1(17) applies. But it seems needlessly complex to require the existence of components to make this check. Should this aggregate be rejected? (Yes.)
Similarly:
type Enum is (One, Two, Three); type Variant_Record_3 (Disc : Enum; Disc2 : Boolean) is record case Disc is when One => I : Integer; case Disc2 is when True => J : Integer; when False => null; end case; when Two => F : Float; when Three => null; end case; end record;
Variant_Record_3' (Disc => Two, Disc2 => Function_Call, F => 2.0);
Here, Disc2 is dynamic, but it is known to not control a variant since Disc is statically known to be Two. Should this aggregate be rejected? (No.)
!recommendation
(See Wording.)
!wording
Replace 4.3.1(17)
If the components of a variant_part are needed, then the value of a discriminant that governs the variant_part shall be given by a static expression.
with
The value of a discriminant that governs a variant_part P shall be given by a static expression, unless P is nested within a variant V that is not selected by the discriminant value governing the variant_part enclosing V.
!discussion
The existing wording is quite clear that it applies only when there are actually components. However, as the questioner points out, this makes little sense since it makes the interpretation of the rule dependent on discriminant values that aren't necessarily known when this rule is enforced. Essentially, the rule is circular in that it depends on itself in order to be understandable.
Thus we adopt a rule that does not depend on components that are "needed". For this new rule, the variants of the variant_part P mentioned in the wording play no role. In particular, it makes no difference whether the variant_part P contains no component_declararations.
This interpretation is technically an incompatibility, as aggregates containing a variant_part with no components controlled by a dynamic discriminant are now rejected, while with the old rule these appear to be legal. This incompatibility would be rare in practice. Moreover, a survey of existing compilers show that all reported (GNAT, Irvine, AdaMagic, Janus/Ada) actually do not consider whether a variant has components in enforcing 4.3.1(17). Thus, the incompatibility does not exist in practice (compilers already reject such programs).
Note that wording following "unless" exists to allow the last example of the
!question to remain legal. This is necessary to avoid an unnecessary
incompatibility: 3 out of 4 existing compilers currently allow this example. There seems to be no important reason to change this result.
Finally, the following example was illegal before this change and remains illegal:
type T1 (D1 : Boolean) is tagged record case D1 is when False => C : Character; ... when True => S : String(1..10); ... end case; end record;
type T2 (D2 : Integer) is new T1 (D1 => Some_Non_Static_Value) with ...;
X2 : T2 := (D2 => 123, ....); -- Illegal
In this case, the offending non-static discriminant value for D1 does not occur within the aggregate, but the rule still applies and the aggregate is illegal.
!corrigendum 4.3.1(17)
Replace the paragraph:
If the components of a variant_part are needed, then the value of a discriminant that governs the variant_part shall be given by a static expression.
by:
The value of a discriminant that governs a variant_part P shall be given by a static expression, unless P is nested within a variant V that is not selected by the discriminant value governing the variant_part enclosing V.
!ACATS Test
Add an additional ACATS B-Test to check that the corner cases clarified by this AI (see the !appendix for part of a possible test).
!appendix

!topic Definition of "needed component"
!reference 4.3.1
!from Adam Beneschan 10-03-16
!discussion


While looking over the record aggregate rules when responding to a recent
comp.lang.ada post, it occurred to me that the rules regarding components in
variant parts might be incorrect.

Consider:

   type Enum is (One, Two, Three);
   type Variant_Record (Disc : Enum) is record
      case Disc is
         when One =>
            I : Integer;
         when Two =>
            F : Float;
         when Three =>
            null;
      end case;
   end record;

For a record_aggregate of type Variant_Record, 4.3.1(9) says that "all
copmonents of the value defined by the aggregate are needed".  This means that
the "needed components" depend on the value of the discriminant (and 9.a in the
AARM says so explicitly).  Thus, for example, in (Disc => One, I => 5), F is not
needed, and for (Disc => Three), neither I nor F is needed.

4.3.1(17) says, "If the components of a variant part are needed, then the value
of a discriminant that governs the variant_part shall be given by a static
expression".  But, by 4.3.1(9), whether "the components of a variant part are
needed" depends on the actual value of the discriminant, and thus can't be
determined statically.  So in this case:

   Variant_Part' (Disc => Function_Call(Param));

If the function returns Three, then 4.3.1(17) wouldn't apply, since no
components of a variant part are needed, and thus the aggregate would be legal.
This can't make sense---certainly, the legality of the aggregate can't depend on
what the function is going to return at runtime!

So I think 4.3.1(17) is worded incorrectly.  Maybe it can be solved by defining
the concept of a variant_part being "needed"; change 4.3.1(9) to:

For the record_component_association_list of a record_aggregate, all components
of the composite value defined by the aggregate are needed; for the association
list of an extension_aggregate, only those components not determined by the
ancestor expression or subtype are needed (see 4.3.2). For the
record_component_association_list of a record_aggregate, if the aggregate's type
has a variant_part, then that variant_part is needed; for the association list
of an extension_aggregate, variant_parts that are part of the aggregate's type,
and that are not part of a record type that is an ancestor of the ancestor
expression's type or of the ancestor subtype, are needed. Each selector_name in
..."

and then change 4.3.1(17) to "If a variant_part is needed, then the value of a
discriminant that governs the variant_part shall be given by a static
expression".

Note: GNAT rejects this, which I think is correct:

   type Variant_Record_2 (Disc : Enum) is record
      case Disc is
         when others => null;
      end case;
   end record;
   R : Variant_Record_2 := (Disc => <something-nonstatic>);

but one could argue from the rules as currently written that this should be
legal since there is no possibility that a component in a variant part would be
"needed".  If the *intent* is for this to be legal, then my proposed change
would be an incompatibility.  I'm sort of guessing that this isn't a problem.

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

From: Adam Beneschan
Sent: Thursday, March 18, 2010  10:40 PM

I realized this morning that this isn't quite correct and would introduce an
incompatibility.  In this case:

   type Enum is (One, Two, Three);
   type Variant_Record (Disc : Enum; Disc2 : Boolean) is record
      case Disc is
         when One =>
            I : Integer;
            case Disc2 is
                when True =>
                    J : Integer;
                when False =>
                    null;
            end case;
         when Two =>
            F : Float;
         when Three =>
            null;
      end case;
   end record;

the aggregate

   Variant_Record' (Disc => Two, Disc2 => B, F => 2.0);

should be legal even if B is nonstatic; since Disc is statically determined to
be Two, the variant part governed by Disc2 isn't used. But the way I worded it,
the variant_part governed by Disc2 would still be "needed", because it's there.
So another sentence should be added to my proposed wording:

    For the record_component_association_list of a record_aggregate,
    if the aggregate's type has a variant_part, then that variant_part
    is needed; for the association list of an extension_aggregate,
    variant_parts that are part of the aggregate's type, and that are
    not part of a record type that is an ancestor of the ancestor
    expression's type or of the ancestor subtype, are needed.  In
    either case, though, a variant_part that is part of the
    component_list of an enclosing variant_part is needed only if the
    enclosing variant_part is needed, and if the discrete_choice_list
    for the component_list containing the inner variant part covers
    the value [which must be static] of the discriminant that governs
    the enclosing variant_part.

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

From: Steve Baird
Sent: Monday, August 2, 2010  6:52 PM

Randy and I have been discussing solving the problem identified in this AI by
replacing 4.3.1(17)

   If the components of a variant_part are needed, then the value of a
   discriminant that governs the variant_part shall be given by a static
   expression.

with something along the lines of

   If the value of a discriminant that governs a variant_part
   determines which components are needed, then the value of that
   discriminant shall be given by a static expression. The variants of
   the given variant_part play no role in determining the applicability
   of this rule.

   AARM note:
   For example, a variant_part which contains no component_declarations
   in any of its variants is treated the same (with respect to this rule)
   as a variant_part which contains component_declarations.

The second sentence is intended to clarify the meaning of he word "determines"
in the first sentence. We don't want to have to worry about oddball corner cases
where one could argue that a nonstatic discriminant might be allowed.

On the other hand, it seems important that we do allow a non-static discriminant
to govern a nested variant part in the case where the (static) discriminant
value governing an enclosing variant_part did not select the enclosing variant
of the variant_part in question.

The above wording is intended to accomplish this and is hoped to be just a
confirmation of existing practice for implementations. This has been confirmed
for the GNAT compiler.

This AI is not intended to make work for implementers. The goal is to define the
"nobody cares" corner cases in a way that is consistent with existing common
practice. The test given below can be used to check whether an existing
implementation already implements the proposed rule. Randy reports that the
Janus compiler rejects the 4 aggregates marked "ERROR", but also rejects the
aggregate marked "legal". Results from other compilers could be useful in
evaluating this proposal.

Comments?

   -- Steve

=====

   procedure Corner_Cases (Non_Static : Boolean) is

      type T1 (D : Boolean) is
        record
          case D is
            when False => null;
            when True => null;
          end case;
        end record;

      X1 : T1 := (D => Non_Static); -- ERROR

      type T2 (D : Boolean) is
        record
          case D is
            when Boolean => null;
          end case;
        end record;

      X2 : T2 := (D => Non_Static); -- ERROR

      type T3 (D : Natural) is
        record
          case D is
            when Natural => null;
            when others  => Unlikely : Float;
          end case;
        end record;

      X3 : T3 := (D => Boolean'Pos (Non_Static)); -- ERROR

      type T4 (D1, D2 : Boolean) is
        record
          case D1 is
            when False => null;
            when True =>
              case D2 is
                when False => null;
                when True => Int : Integer;
              end case;
          end case;
        end record;

      X4_A : T4 := (D1 => Non_Static, D2 => False); -- ERROR
      X4_B : T4 := (D1 => False, D2 => Non_Static); -- legal

    begin
       null;
    end Corner_Cases;

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

From: Dan Eilers
Sent: Monday, August 2, 2010  7:05 PM

>                               Randy reports that the Janus compiler
> rejects the 4 aggregates marked "ERROR", but also rejects the
> aggregate marked "legal". Results from other compilers could be useful
> in evaluating this proposal.

Our compiler rejects the 4 aggregates marked "ERROR", and accepts the one marked
"legal".

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

From: Tucker Taft
Sent: Monday, August 2, 2010  7:22 PM

I don't find the second sentence as being very helpful.  Better might be to put
it into the AARM note and make the AARM note more explicit.

I wonder whether it might be better to make the following incremental wording
change:

    If the components of a variant_part are needed, {even if
    there are none,} then the value of a discriminant that
    governs the variant_part shall be given by a static
    expression.

I don't think your rewording really solves the problem anyway, since if all
variant alternatives are "null" then you are back to the situation where there
are no components, so the value of the discriminant might be thought to be
irrelevant depending on the interpretation. I suppose your second sentence was
supposed to clarify, but it really didn't help me at all.

For the record, the AdaMagic front end complains about the aggregates just as
you predicted in your "Corner_Cases" example, so with my vendor hat on, I
support the proposed "interpretation" of this rule that you have suggested.

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

From: Steve Baird
Sent: Tuesday, August 3, 2010  12:44 PM

> I don't find the second sentence as being very helpful.  Better might
> be to put it into the AARM note and make the AARM note more explicit.

Would it be better if we spell things out more explicitly?

   The value of a discriminant that governs a variant_part shall be
   given by a static expression, unless
     - the variant_part occurs within an enclosing (not necessarily
       immediately enclosing) variant_part; and
     - the variant enclosing the enclosed variant_part is not
       selected by the discriminant value governing the enclosing
       variant_part.

If it seems necessary, we could add another item in the middle
of that bulleted list:

     - the value of the discriminant that governs the enclosing
       variant_part is given by static expression; and

I don't think this is necessary.

The problem I see with this approach is illustrated by the
following example:

    type T1 (D1 : Boolean) is
      record
        case D1 is
          when False => null;
          when True => Int : Integer;
        end case;
      end record;

    type T2 (D2 : Boolean) is new T1 (D1 => Some_Non_Static_Value)
      with null record;

     X : T2 := (D2 => False); -- must be illegal

It is not clear (at least to me) that the wording I've proposed
above covers this case. We want to reject this because the
variant_part in T1 (or perhaps the inherited copy thereof in T2,
although the RM never speaks of inheriting a variant_part)
is governed by Some_Non_Static_Value, an expression which doesn't
even occur in the aggregate.

The original wording handled this case by making use of the
term "needed".

I suppose we could adopt a belt-and-suspenders approach, modifying
the wording suggested above by replacing

   The value of a discriminant that governs a variant_part shall be
   given by a static expression, unless

with

  The value of a discriminant that governs a variant_part whose
  components are needed shall be given by a static expression, unless

and then adding an AARM note to confirm that the phrase
"whose components are needed" does indeed apply to a
componentless variant_part.

This seems clunky, but I don't see an elegant solution.

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

From: Tucker Taft
Sent: Tuesday, August 3, 2010  1:00 PM

I guess I still prefer the wording I proposed:

    If the components of a variant_part are needed, {even if
    there are none,} then the value of a discriminant that
    governs the variant_part shall be given by a static
    expression.

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

From: Steve Baird
Sent: Tuesday, August 3, 2010  1:46 PM

It seems to me that any rule that starts with

    If the components of a variant_part have some property,
    even if there are none, then ...

would, based on a strict reading, apply uniformly to all componentless
variant_parts.

We want this rule to apply to some componentless variant_parts but not to
others, depending on whether the components of the variant_part would have been
needed if only the variant_part had components.

I don't think the wording you've suggested accomplishes this, at least if it is
read strictly.

On the other hand, this point is fairly pedantic.

I could live with the wording that you suggest if we add AARM text (preferably a
"To Be Honest" note) to clarify what is really meant.

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

From: Tucker Taft
Sent: Tuesday, August 3, 2010  2:08 PM

Given that this is a corner case, I am reluctant to add a bunch of words to the
RM.  Adding words to clarify things in the AARM is fine with me. Apparently all
of the implementors interpreted this the same way, and as far as I know no
"real" user has complained about this, so going overboard in an RM explanation
seems a waste of everyone's energy.

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

From: Tucker Taft
Sent: Tuesday, August 3, 2010  2:15 PM

How about:

       If the components of a variant_part are needed, {even if
       there are none *in the chosen variant*,} then the value of
       a discriminant that governs the variant_part shall be
       given by a static expression.

This make the extra phrase somewhat more useful even in a non-corner case where
some but not all of the variants of the variant part have components.  To cover
the silly case where none of the variants have components, we can add a "to be
honest".

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

From: Steve Baird
Sent: Tuesday, August 3, 2010  2:46 PM

My first reaction was to agree with your analysis and view this as an
improvement.

On the other hand, it seems that we are introducing a circularity in talking
about "the chosen variant" in the legality rule which is, in turn, needed to
ensure that "the chosen variant" is well defined. At the very least, this is
potentially confusing.

Given this, I don't think this addition would be an improvement.
It's a close call (for me) and, as before, I could live with this as long as the
AARM tells the full story.

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

From: Randy Brukardt
Sent: Tuesday, August 3, 2010  4:10 PM

...
> It seems to me that any rule that starts with
>
>     If the components of a variant_part have some property,
>     even if there are none, then ...
>
> would, based on a strict reading, apply uniformly to all componentless
> variant_parts.

Isn't that what we want?

> We want this rule to apply to some componentless variant_parts but not
> to others, depending on whether the components of the variant_part
> would have been needed if only the variant_part had components.

I can't parse this at all. Could you remind me which of the corner case(s) you
are concerned about here?

> I don't think the wording you've suggested accomplishes this, at least
> if it is read strictly.
>
> On the other hand, this point is fairly pedantic.

It's beyond pedantic, it defies understanding. ;-)

> I could live with the wording that you suggest if we add AARM text
> (preferably a "To Be Honest" note) to clarify what is really meant.

I guess I'd like to know what is really meant before agreeing or disagreeing
with this.

Steve later says:

>> How about:
>>
>>       If the components of a variant_part are needed, {even if
>>       there are none *in the chosen variant*,} then the value of
>>       a discriminant that governs the variant_part shall be
>>       given by a static expression.
>
...
>On the other hand, it seems that we are introducing a circularity in talking
>about "the chosen variant" in the legality rule which is, in turn, needed to
>ensure that "the chosen variant" is well defined. At the very least, this is
>potentially confusing.

Doesn't this logic apply to any wording containing "needed" as well? After all,
it is the discriminant values that determine what components are needed
(especially in nested variants). Adam's original complaint about this wording
was the circularity of "needed" and this rule.

The fact that no one actually implements the rule as written was something that
Steve and I realized while we were discussing fixes to Adam's original
complaint.

I agree that everyone seems to have interpreted this the same (with a slight
difference in Janus/Ada), but that doesn't address the wording confusion that
Adam pointed out. So I think I prefer Steve's earlier proposal, as it doesn't
suffer from this circularity.

Indeed, I would prefer to simply say:

   The value of a discriminant that governs a variant_part shall be
   given by a static expression.

since no one has explained to me why there is any value to allowing a non-static
discriminant that controls an unselected variant. At a minimum, that seems to be
a design problem (using a single discriminant for multiple purposes); if it is
simply a "don't care" discriminant (which I would hope), why would using a
static discriminant be a hardship??

But I realize that this would introduce an incompatibility (of the best kind
- detected at compile-time), so I suppose we need the extra wording:

   The value of a discriminant that governs a variant_part shall be
   given by a static expression, unless the variant_part V occurs within an
   enclosing (not necessarily immediately enclosing) variant_part E and
   the variant enclosing V is not selected by the discriminant value
   governing E.

(I introduced the names "V" and "E" to clearly mark which variant_part is which
in this wording -- there are just too many "enclosing"s in Steve's original
wording; once done, the bullets didn't seem necessary. I considered not
introducing "E", it doesn't help as much as "V" does, but I went with the
shortest wording.)

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

From: Steve Baird
Sent: Tuesday, August 3, 2010  4:27 PM

> ...
>> It seems to me that any rule that starts with
>>
>>     If the components of a variant_part have some property,
>>     even if there are none, then ...
>>
>> would, based on a strict reading, apply uniformly to all
>> componentless variant_parts.
>
> Isn't that what we want?
>

No.

>> We want this rule to apply to some componentless variant_parts but
>> not to others, depending on whether the components of the
>> variant_part would have been needed if only the variant_part had
>> components.
>
> I can't parse this at all. Could you remind me which of the corner
> case(s) you are concerned about here?
>

      type T4 (D1, D2 : Boolean) is
        record
          case D1 is
            when False => null;
            when True =>
              case D2 is
                when False => null;
                when True => Int : Integer;
              end case;
          end case;
        end record;

      X4_B : T4 := (D1 => False, D2 => Non_Static); -- legal

We want the above aggregate to be legal. If the rule applied to every
veriant_part, then it would be rejected.

> Indeed, I would prefer to simply say:
>
>    The value of a discriminant that governs a variant_part shall be
>    given by a static expression.

That rule would be consistent with what Janus implements and would cause the
X4_B aggregate above to be rejected.

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

From: Steve Baird
Sent: Tuesday, August 3, 2010  4:43 PM

> Doesn't this logic apply to any wording containing "needed" as well?
> After all, it is the discriminant values that determine what
> components are needed (especially in nested variants). Adam's original
> complaint about this wording was the circularity of "needed" and this rule.

Yes, you are right. That circularity seems to have been granted a "grandfather"
clause on the grounds that a really correct rule requires too much RM wording.
That doesn't necessarily mean that we want to introduce another circularity, but
I'd agree that it weakens the argument against adding another one.

> But I realize that this would introduce an incompatibility (of the
> best kind
> - detected at compile-time), so I suppose we need the extra wording:
>
>    The value of a discriminant that governs a variant_part shall be
>    given by a static expression, unless the variant_part V occurs within an
>    enclosing (not necessarily immediately enclosing) variant_part E and
>    the variant enclosing V is not selected by the discriminant value
>    governing E.

If you drop the use of "needed", then how do you handle things like

      type T1 (D1 : Boolean) is
          tagged record
             case D1 is
               when False => null;
               when True => Int : Integer;
             end case;
          end record;

     type T2 (D2 : Integer) is new T1 (Some_Non_Static_Value)
       with null record;

     X2 : T2 := (D2 => 123); -- must be illegal

In this case, the problematic non-static discriminant value does not occur in
the aggregate. With the wording you've suggested, it sounds like we iterate over
the discriminants in the aggregate, but that's not good enough in the above
case. The current wording handles this by use of the word "needed".

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

From: Randy Brukardt
Sent: Tuesday, August 3, 2010  4:59 PM

> In this case, the problematic non-static discriminant value does not
> occur in the aggregate. With the wording you've suggested, it sounds
> like we iterate over the discriminants in the aggregate, but that's
> not good enough in the above case. The current wording handles this by
> use of the word "needed".

I *don't* handle anything; you are the one that suggested this wording (I just
cleaned it up to eliminate the feeling that this was "a lot of new wording".

But I don't even see the problem that you are complaining about here. You
carefully worded this so that it says "the discriminant that governs a variant
part" -- it makes no requirement that that discriminant appears in the
aggregate! (I recall us discussing this in the past.) I would say that an AARM
note to point this out (that the discriminant could be given in a derivation
only and not appear in the aggregate) would be sufficient.

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

From: Steve Baird
Sent: Tuesday, August 3, 2010  5:24 PM

You're right. This AI is making me punchy.

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

From: Tucker Taft
Sent: Tuesday, August 3, 2010  4:36 PM

[Editor's note: This message appears to be a reply to Steve's message of
2:46 PM, but no message was quoted.]

OK, how about:

     If the components of a variant_part are needed {(even if
     there are no components in some of its variants)},
     then the value of a discriminant that governs the variant_part
     shall be given by a static expression.

I really hate to see this definition get a lot longer.
By parenthesizing hopefully we reduce even further the need for the casual user
to worry about it.

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

From: Steve Baird
Sent: Tuesday, August 3, 2010  5:17 PM

> OK, how about:
>
>     If the components of a variant_part are needed {(even if
>     there are no components in some of its variants)},
>     then the value of a discriminant that governs the variant_part
>     shall be given by a static expression.

I can live with any of the recent alternatives you've suggested (with an
accompanying AARM explanation).

I don't feel strongly about it.

> I really hate to see this definition get a lot longer.
I think everyone is agreed on that point.

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

From: Randy Brukardt
Sent: Tuesday, August 3, 2010  4:51 PM

> OK, how about:
>
>      If the components of a variant_part are needed {(even if
>      there are no components in some of its variants)},
>      then the value of a discriminant that governs the variant_part
>      shall be given by a static expression.
>
> I really hate to see this definition get a lot longer.
> By parenthesizing hopefully we reduce even further the need for the
> casual user to worry about it.

I still object to using "needed" in this wording, as it is not well-defined
until after this rule is applied. (That is, if the discriminants are non-static,
how do you figure out if a component or variant is needed?? We don't want to go
there.)

I agree about making this definition "a lot longer", but the proposed rewording
I suggested is not a lot longer.

   The value of a discriminant that governs a variant_part shall be
   given by a static expression, unless the variant_part V occurs within an
   enclosing (not necessarily immediately enclosing) variant_part E and
   the variant enclosing V is not selected by the discriminant value
   governing E.

Resorting to word counts, Tucker's wording has 36 words; my rewording (of
Steve's older proposal) has 44 words (or 22% larger). 22% is not a lot in RM
terms!!

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

From: Tucker Taft
Sent: Tuesday, August 3, 2010  5:12 PM

Or shorter:

     The value of a discriminant that governs a variant_part P
     shall be given by a static expression, unless P is nested within
     a variant V that is not selected by the discriminant value
     governing the variant_part enclosing V.

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

From: Steve Baird
Sent: Tuesday, August 3, 2010  5:20 PM

I like it.

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

From: Randy Brukardt
Sent: Tuesday, August 3, 2010  5:32 PM

Goody: 38 words, only 5% larger. ;-)

P.S. Looks OK to me.

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

From: Randy Brukardt
Sent: Tuesday, August 3, 2010  5:34 PM

> You're right. This AI is making me punchy.

Well, all you have to do now is write it up, using Tucker's rewrite of my
rewrite of your older proposed wording.

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


Questions? Ask the ACAA Technical Agent