[net.lang.ada] Variant Record field names

emery@gypsy.UUCP (06/11/86)

Here's some interesting "variations" on variant records:

   1:package variant_record_confusion is
   2:  
   3: 	type r1 (desc : boolean) is 	-- start with legal case
   4: 	  record
   5:	    case desc is
   6:	      when true =>
   7:		true_field : integer;
   8:	      when false =>
   9:		false_field : integer;
  10:	    end case;
  11:	end record;
  12:
  13:	type r2 (desc : boolean) is 	-- now an illegal case
  14: 	  record
  15:	    case desc is
  16:	      when true =>
  17:		field : integer;
  18:	      when false =>
  19:		field : integer;
A --------------^
A:error: RM 8.7(1): declaration cannot overload field, line 17
  20:	    end case;
  21:	end record;
  22:
  23:	type r3 (desc : boolean) is 	-- but this is ok
  24: 	  record
  25:	    case desc is
  26:	      when true | false =>
  27:		field : integer;
  28:	    end case;
  29:	end record;
  30:
  31:
  32:end variant_record_confusion;

So, in r1, the two field names were different, but they were the same in r2.
But, this is illegal (RM citation courtesy of our Verdix compiler).  
However, look at r3.  Here we have the two cases lumped together, and
they 'share' the same declaration.

At face value, this seems to violate the "sacred language principle" that

	case x is
	  when choice1 | choice2 =>
	    alternative;
	...
	end case;

is the same is

	case x is
	  when choice1 =>
	    alternative;
	  when choice2 =>
	    alternative;
	...
	end case;

which seems to be true for case STATEMENTS.  

My co-worker, Eric Smith, noted that one reason for this restriction in
variant records is that, in the "x | y" construct, the compiler knows exactly,
at compile time, how to reference "field".  

Consider this, he says:

	type r4 (descr : boolean := false) is	-- not legal
	  record
	    case descr is
	      when true =>
		field : integer;
	      when false =>
		field : some_other_type;
	    end case;
	end record;

	x,y : r4;

	...
	
	x.field := y.field;

The compiler does not know at compile time if x.field is an integer, or
some_other_type.  Overload resolution doesn't work either, as the same
holds true for y.field, too.  It would require run-time code to determine
if the assignment is legal.  

Things get even worse in the next example:

	type r5 (descr : boolean := true) is
	  record
	    when true =>
	      a : integer;
	      b : some_other_type;
	    when false =>
	      a : some_other_type;
	      b : integer;
	    end case;
	end record;

        x, y : r5;
	...
	x.a := y.a;

(Proof of how messy this would get is left to the reader, which means I
 am too lazy to completely explain it...)

We had a bit of a discussion on the "whys" and "what ifs" of variant
record field names, and this note tries to sum it all up.

Share and enjoy!

				Dave Emery
				Siemens Research
		   ...princeton!siemens!emery
		      princeton!siemens!emery@seismo.css.gov or
					     @topaz.rutgers.edu