[comp.lang.ada] Redefinition of "=" and related iss

stt@ada-uts (01/06/88)

I think the basic reason for restricting user-defined "="
to limited types is that non-limited types may be combined
into aggregates where the predefined "=" will again take effect.
In other words, an array of rational numbers would use
the predefined "=" even though there might be a user-defined
"=" for single rational numbers.
In fact, this limitation can be worked around using
a generic instantiation trick which I first saw demonstrated
by John Goodenough (see below for details).

With hindsight, I personally find the limitation undesirable.
I think it was an attempt to protect
programmers from themselves, but as you point out it really
gets in the way of doing decent abstract data type packages.
Ada as protector seems like the wrong approach.
Programmers should be able to create protected data structures,
but they should not be prevented from creating unprotected structures.

As far as ":=" the limitations seem to be largely
syntactic.  Clearly a user-defined ":=" would be a procedure
rather than a function.  It would also have special
visibility properties (i.e. it would be directly visible
anywhere the type is accessible, rather than only when "use"d
or scoped-in).  It also has the same issue with aggregates
as "=", namely that ":=" for an array of non-limited private
would use the predefined ":=" even if there were a user-defined
":=" for individual objects.

------------------------------------------------
Here is the trick for defining "=" on non-private types:

generic
    type Non_Limited is limited private;
       -- Although this says "limited private" it may be instantiated
       -- with a non-limited type.
    with function Equal(Left, Right : Non_Limited) return Boolean is <>;
       -- user-defined equality
package Define_Equals is
    function "="(Left, Right : Non_Limited) return Boolean
      renames Equal;
        -- Rename of user-defined equality, legal since
	-- type is "formally" limited.
end Define_Equals;

. . .

type My_Type is ...  -- Some non-limited type
function Equal(Left, Right : My_Type) return Boolean is ...
  -- User-defined equality

package My_Equals is new Define_Equals(My_Type, Equal);

function "="(Left, Right : My_Type) return Boolean renames My_Equals."=";
   -- Rename of user-defined equality, legal since
   -- it is renaming XXX."=" as "="
   
-- We have now produced a user-defined overload of "=" on
-- a non-limited type.

Tnx to John Goodenough (and others probably)

S. Tucker Taft
c/o Intermetrics, Inc.
Cambridge, MA  02138