[comp.lang.ada] Overloading of assignment

madmats@elma.epfl.ch (Mats Weber) (11/25/88)

The question of what an overloaed assignment procedure should look like still
remains:

  variant A:

  procedure ":=" (OBJECT : out SOME_LIMITED_TYPE;
                  VALUE  : in  SOME_LIMITED_TYPE);

  variant B:

  procedure ":=" (OBJECT : in out SOME_LIMITED_TYPE;
                  VALUE  : in     SOME_LIMITED_TYPE);

The problem with variant A is that if SOME_LIMITED_TYPE has subcomponents that
are of an access type, then no garbage collection can be performed on OBJECT
before assigning it its new value, because OBJECT cannot be read inside ":=".

The problem with variant B is that it cannot be used for the initialization
of an object (unless SOME_LIMITED_TYPE is an array or record type) because the
actual parameter for OBJECT must have a defined value before the use of ":="
(otherwise the program is erroneous). Consider the following example:

   package ADT is

      type T is limited private;

      procedure ":=" (OBJECT : in out T; VALUE : in T);

      function TO_T (N : INTEGER) return T;

   private

      type T is range 0..1000;

   end ADT;

   with ADT;
   procedure P is

      X : ADT.T;

      use ADT;

   begin
      X := TO_T(7);    -- this call of ":=" is erroneous because X
   end P;              -- is undefined.


Variant A is better if SOME_LIMITED_TYPE is a scalar type,
variant B is better if SOME_LIMITED_TYPE is an array or record type,
both variants work with access types as these always have the initial value
null.

Personally, I think the rules on assignment in Ada cannot be changed if
upward compatibility is to be acheived.

Mats Weber
DI-LITh-EPFL
Swiss Federal Institute of Technology
1015 Lausanne
Switzerland

e-mail : madmats@elma.epfl.ch

billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) (11/27/88)

From article <881125130910.218003ab@elcc.epfl.ch>, by madmats@elma.epfl.ch (Mats Weber):
! Consider the following example:
! 
#    package ADT is
#       type T is limited private;
#       procedure ":=" (OBJECT : in out T; VALUE : in T);
$       function TO_T (N : INTEGER) return T;
$    private
$       type T is range 0..1000;
%    end ADT;
% 
%    with ADT; use ADT;
&    procedure P is
&       X : ADT.T;
*    begin
*       X := TO_T(7);    -- this call of ":=" is erroneous because X
*    end P;              -- is undefined.

 The solution is to enable any type of object to be automatically initialized;
 any type of object should be able to carry the value "undefined", which is
 automatically assumed by all objects not otherwise initialized.  

 The value "null" would be an alias for "undefined", to preserve compatibility.

 In the case of integers, for example, we typically have the range
    31    31                            31        31
  -2  .. 2  - 1; this would shrink to -2  - 1 .. 2  - 1, using the
                      31
 liberated value of -2  as our representation of "undefined", and
 rendering the range of an integer symmetrical, thus eliminating
 the problem of having -1 * MAXINT raise a NUMERIC_ERROR.

billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) (11/27/88)

From article <3667@hubcap.UUCP>, by billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,):
#  In the case of integers, for example, we typically have the range
%     31    31                            31        31
%   -2  .. 2  - 1; this would shrink to -2  - 1 .. 2  - 1, using the
%                       31
$  liberated value of -2  as our representation of "undefined", and
$  rendering the range of an integer symmetrical, thus eliminating
$  the problem of having -1 * MAXINT raise a NUMERIC_ERROR.
                                                    31         31
   Technical corrections: the new range would be -(2  - 1) .. 2  - 1,
                          and -1 * MIN_INT would no longer raise
                          NUMERIC_ERROR (or CONSTRAINT_ERROR or whatever).

leake@cme-durer.ARPA (Stephe Leake) (11/30/88)

In article <3667@hubcap.UUCP> billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) writes:

>    The solution is to enable any type of object to be automatically initialized;
>    any type of object should be able to carry the value "undefined", which is
>    automatically assumed by all objects not otherwise initialized.  
>
>    The value "null" would be an alias for "undefined", to preserve compatibility.

But "null" for access types is _not_ the same as "undefined"! I often
use "null" to terminate a list; I do not want all that code to
suddenly be declared erroneous!

>    In the case of integers, for example, we typically have the range
>       31    31                            31        31
>     -2  .. 2  - 1; this would shrink to -2  - 1 .. 2  - 1, using the
>			 31
>    liberated value of -2  as our representation of "undefined", and
>    rendering the range of an integer symmetrical, thus eliminating
>    the problem of having -1 * MAXINT raise a NUMERIC_ERROR.

This is a neat idea; similar to NAN's (Not A Number) in IEEE floating
point. Unfortunately, it is not supported by any hardware I know of.

For enumeration types, the compiler can simply add one more for
undefined; but this might violate a representation clause (for
instance, if I define a type CHAR8 to have 256 elements, represented
in 8 bits, adding an "undefined" would require more bits).

I think, to be truly general, representing "undefined" would force a
record representation for all types, with a discriminant labeling the
object as defined or not. This would be far too much overhead.

I think the origninal Ada concept of an erroneous program is more practical.

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899