comp.lang.ada
 help / color / mirror / Atom feed
From: mheaney@ni.net (Matthew Heaney)
Subject: Making Predefined Operators Abstract
Date: 1997/12/06
Date: 1997-12-06T00:00:00+00:00	[thread overview]
Message-ID: <mheaney-ya023680000612971431120001@news.ni.net> (raw)
In-Reply-To: 66c2rb$hdg$1@peuplier.wanadoo.fr


In article <66c2rb$hdg$1@peuplier.wanadoo.fr>, "Jean-Pierre Rosen"
<rosen.adalog@wanadoo.fr> wrote:

>Robert Dewar said
>>Matthew says
>>
>><<Good advice.  For low-level I/O, an enumeration type is often not what
>you
>>want anyway.  What's wrong with a good old fashioned integer type?
>>>>
>>
>>For one thing, it provides operations like addition, which are probably
>>meaningless nonsense.
>>
>Sure, but don't forget that you can forbid direct calls by redefining the
>functions as abstract.
>
>(Just taking the opportunity to remind people of that relatively unknown
>feature)

I like to do that so I don't use the predefined equality for arrays or
records accidently, because the predefined equality of the component
reemerges.  For example, if I implemented a stack this way

generic
   type Stack_Item is private;
   Max_Depth : Positive;
package Stacks is
   type Bounded_Stack is tagged private;
  
   function "=" (L, R : Bounded_Stack) return Boolean;
...
private

   subtype Top_Range is Natural range 0 .. Max_Depth;

   subtype Item_Array_Range is Top_Range range 1 .. Top_Range'Last;
   type Item_Array is array (Item_Array_Range) of Stack_Item;

   type Bounded_Stack is
      tagged record
         Items : Item_Array;
         Top     : Top_Range := 0;
      end record;

end Stacks;

package body Stacks is

   function "=" (L, R : Bounded_Stack) return Boolean is
   begin
      return L.Items (1 .. L.Top) = R.Items (1..R.Top);
   end;
...
end Bounded_Stacks;

The problem with this implementation of equality is that it's probably
wrong.  The predefined equality operation for Stack_Item reemerged by not
explicitly importing the equality operation as a formal operation.  So I
would do this:

generic
   type Stack_Item is private;
   with function "=" (L, R : Stack_Item) return Boolean is <>;
package Bounded_Stacks is ...;

However, the equality operation for Stack that I defined above is still
wrong!  The problem now is that predefined equality reemerged as a result
of making Stack_Item an array component  Array comparisons use the
predefined equality of the component, in spite of the fact that equality
was imported as a formal operation.  The solution is to not use array
comparison at all to implement stack comparision:

   function "=" (L, R : Bounded_Stack) return Boolean is
   begin
      if L.Top /= R.Top then
         return False;
      end if;

      for Index in Item_Array_Range range 1 .. L.Top loop
         if L.Items (Index) /= R.Items (Index) then
            return False;
         end if;
      end loop;
  
      return True;
   end "=";

All of this was leading up to making a predefined operation abstract. 
Because we definately do not want to use array comparison, we take it away
as follows:

private
   ...
   type Item_Array is array (Item_Array_Range) of Stack_Item;

   function "=" (L, R : Item_Array) return Boolean is abstract;  -- Note
this line

   type Bounded_Stack is ...;

Now neither you nor a naive maintenance programmer can accidently use array
equality, because that operation is abstract.

A guideline for writers of data structures is to always import equality (to
give the client the opportunity to use his own definition) and to not use
predefined array equality for an array having the imported type as a
component.  You must invoke the imported equality of the component type
directly.  Declaring the array equality as abstract enforces this.

--------------------------------------------------------------------
Matthew Heaney
Software Development Consultant
<mailto:matthew_heaney@acm.org>
(818) 985-1271




      reply	other threads:[~1997-12-06  0:00 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-12-03  0:00 Ada Enumerations Jeffrey Harris
1997-12-03  0:00 ` James S. Rogers
1997-12-03  0:00   ` Robert Dewar
1997-12-03  0:00     ` Stanley R. Allen
1997-12-04  0:00       ` GNAT'Object_Size Mats Weber
1997-12-05  0:00         ` GNAT'Object_Size Mats Weber
1997-12-04  0:00       ` GNAT'Object_Size Mats Weber
1997-12-04  0:00       ` GNAT'Object_Size Mats Weber
1997-12-08  0:00         ` GNAT'Object_Size Mats Weber
1997-12-10  0:00           ` GNAT'Object_Size Robert Dewar
1997-12-04  0:00       ` Ada Enumerations Matthew Heaney
1997-12-04  0:00         ` Stanley R. Allen
1997-12-07  0:00           ` Keith Thompson
1997-12-07  0:00             ` Robert Dewar
1997-12-08  0:00               ` Keith Thompson
1997-12-07  0:00                 ` Matthew Heaney
1997-12-11  0:00                   ` John G. Volan
1997-12-07  0:00             ` Matthew Heaney
1997-12-04  0:00       ` GNAT'Object_Size Mats Weber
1997-12-04  0:00       ` Ada Enumerations Robert Dewar
1997-12-04  0:00         ` Stanley R. Allen
1997-12-18  0:00           ` Wes Groleau
1997-12-04  0:00       ` GNAT'Object_Size Mats Weber
1997-12-04  0:00 ` Ada Enumerations Stephen Leake
1997-12-04  0:00   ` Matthew Heaney
1997-12-04  0:00     ` Robert Dewar
1997-12-06  0:00       ` Jean-Pierre Rosen
1997-12-06  0:00         ` Matthew Heaney [this message]
replies disabled

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