comp.lang.ada
 help / color / mirror / Atom feed
* New language feature to check record coverage?
@ 1997-02-25  0:00 Pierre Van Aswegen
  1997-02-26  0:00 ` Geert Bosch
  0 siblings, 1 reply; 2+ messages in thread
From: Pierre Van Aswegen @ 1997-02-25  0:00 UTC (permalink / raw)



I would like those who collect ideas for the evolution of the language
to tell me what they think of the following idea.  It is unprecedented
in any language I know, but suggested slightly by combining the idea
that the compiler checks that you have an entry for each value in a case
statement and the use of record aggregate assigment to ensure you have a
value for each member of the aggregate.

The need I perceive stems from writing a validation function to certify 
that the values in a record are consistent.  If I change the definition
of the record (or miss a member in the original function), the compiler
is not going to remind me to update the validation function.  (As it
would remind me to fix case statements if I changed an enumeration or to
fix an aggregate assignment of said changed record.)  I have encountered
other situations where I've wished to have some guarantee that I was
addressing every part of a record.

What one needs is a kind of iterator for which the user must supply an
operation for each member of a record.  (Some members can share an
operation.)  A reasonably understandable syntax can be derived from
either case or aggregation.  

type Some_Record is
  record
    A_Member : MemberA;
    B_Member : MemberB;
    ...
  end record;

function Is_Consistent return Boolean is
  Answer : Boolean := True;
begin
  case Members'Some_Record    --* 
    when A_Member => ...;     --*
    when B_Member => ...;     --*
    ...
  end case;
  return Answer;
end Is_Consistent;

function Is_Consistent return Boolean is
  Answer : Boolean := True;
begin
  Members'Some_Record        --*
    (A_Member => ...,        --*
    B_Member => ...,         --* 
    ...)
  return Answer;
end Is_Consistent;
                            *"fantasy Ada"




^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: New language feature to check record coverage?
  1997-02-25  0:00 New language feature to check record coverage? Pierre Van Aswegen
@ 1997-02-26  0:00 ` Geert Bosch
  0 siblings, 0 replies; 2+ messages in thread
From: Geert Bosch @ 1997-02-26  0:00 UTC (permalink / raw)



Pierre Van Aswegen (pvana@iossvr.gm.hac.com) wrote:
  "I would like those who collect ideas for the evolution of the language
   to tell me what they think of the following idea."

Why do you think it is not possible to use the language as-is for
your purposes?

I do not think it is very useful to check consistency of a record on a
field-by-field basis, since a limited form of this is alraeady
available by using the appropriate subtypes in your type definition.

For checking consistency of an entire record, it is not always
necessary to check all fields and just checking all fields is 
not enough.

If you just want to be sure that nobody adds a field to the record
type without looking at your Is_Consistent procedure, just do the
following:

   function Is_Consistent (R : Some_Record_Type) return Boolean is
      Check : constant Some_Record_Type := 
	 	(A_Member => R.A_Member, 
		 B_Member => R.B_Member, 
		 C_Member => R.C_Member);
   begin
      --  Some consistency check
      return Check.A_Member <= Check.B_Member * Check.C_Member;
   end Is_Consistent;
      
This way you have clearly documented all fields in your procedure.

You may find that the approach below also might be useful. I will
try to illustrate it using an example that might occur in a numerical
program that wants to check the consistency of a record containing
the input and result of a calculation.

Consider that we have a record type Cached_Calculation containing 
three floating point values: X, Y and Z. The value Z is the result
of a time-consuming calculation Calculate_Z using X and Y as input. 

For X and Y the constraints are 0 < X <= Y. There are fast algorithms
to Lower_Z and Upper_Z to find an upper- and a lower-bound for the 
value of Z. 

These should be used when checking for consistency of the value Z with
X and Y.  We also want to be certain that no extra calculation parameters
can be added to Cached_Calculation without updating Consistency_Check.

--  Start of example

with Ada.Text_IO;
procedure Checking is

   ----------------
   -- Defintions --
   ----------------

   type Cached_Calculation is 
      record
         X, Y      : Float;
         Z         : Float;
      end record;

   function Calculate_Z (X, Y : in Float) return Float;
   function Lower_Z (X, Y : in Float) return Float;
   function Upper_Z (X, Y : in Float) return Float;

   procedure Consistency_Check (C : in Cached_Calculation);

   function "&" (Left : String; Right : Float) return String;

   --------------------
   -- Implementation --
   --------------------

   function Calculate_Z (X, Y : in Float) return Float is
   begin
      return (X + Y) / 2.0;
   end Calculate_Z;

   function Lower_Z (X, Y : in Float) return Float is
   begin
      return Float'Min (X, Y);
   end Lower_Z;

   function Upper_Z (X, Y : in Float) return Float is
   begin
      return Float'Max (X, Y);
   end Upper_Z;

   procedure Consistency_Check (C : in Cached_Calculation) is
      subtype Valid_X is Float range Float'Succ (0.0) .. Float'Last;
      subtype Valid_Y is Float range C.X .. Float'Last;
      subtype Valid_Z is Float range Lower_Z (C.X, C.Y) .. Upper_Z (C.X, C.Y);

      Valid_C : constant Cached_Calculation :=
        (X => Valid_X (C.X),
         Y => Valid_Y (C.Y),
         Z => Valid_Z (C.Z));
   begin
      null;
   end Consistency_Check;

   function "&" (Left : String; Right : Float) return String is
   begin
      return Left & Float'Image (Right);
   end "&";

   ------------------
   -- Main Program --
   ------------------

   X      : Float := 1.0;
   Y      : Float := 2.0;
   Result : Cached_Calculation;

begin
   Result := (X, Y, Calculate_Z (X, Y));
   Consistency_Check (Result);
   Result.X := Result.X + 0.5;
   Consistency_Check (Result);
   Result.X := Result.X + 0.1;
   Consistency_Check (Result);
exception
   when Constraint_Error =>
      Ada.Text_IO.Put_Line
        (File => Ada.Text_IO.Standard_Error,
         Item => "Error in calculation: "
           & "X =" & Result.X & ", Y =" & Result.Y & ", Z =" & Result.Z);
end Checking;

-- 
--  E-Mail: geert@sun3.iaf.nl    
--    `` If trainstations are places where trains stop, 
--	 then what are workstations? ''




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1997-02-26  0:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-02-25  0:00 New language feature to check record coverage? Pierre Van Aswegen
1997-02-26  0:00 ` Geert Bosch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox