comp.lang.ada
 help / color / mirror / Atom feed
From: TUFFS1@alcoa.com
Subject: Assignment Overloading
Date: 6 Dec 88 13:05:00 GMT	[thread overview]
Message-ID: <8812140455.AA16282@ajpo.sei.cmu.edu> (raw)

I have an observation regarding the overloading of assignment.  A
basic justification seems to be that when building/using an abstract 
data type it becomes tedious to expand functional structures into 
procedural structures.  I agree.  For example:

  X := Y + Z;     versus:  Add(Y, Z, X); 
  X := A + B + C; versus:  Add(A, B, Temp); Add(Temp, C, X); ... etc.

Pre-processing is one solution, but as noted in previous comments, the 
final code is often what matters, and it's ugly. 

To add fuel to the discussion, consider the following code fragment (as 
might occur in a reusable matrix manipulation package):

  type Vectors(Dimension: Positive) is private;
  ...
  function "+"(Left, Right: in Vectors) return Vectors;
  ...
  X, Y, Z: Vectors(3);  
  ...
  X := Y + Z; -- Assuming Y and Z are initialized somewhere above

The problems start when we choose an access type as the private 
representation of Vectors:

  ...
  private
    type Aggregates is array(Positive range <>) of Numbers;
    type Aggregate_Pointers is access Aggregates;
    type Vectors(Dimension: Positive) is record
      Elements: Aggregate_Pointers;
    end record;
    ...

We might do this in order to get pass-by-reference semantics and speed 
up the code. The problem is, what can we do about the storage which may 
already be allocated to X, which will have become unavailable due to the 
implementation of "+":

  function "+"(Left, Right: Vectors) return Vectors is
    Result: Vectors(Left.Dimension) := (Dimension => Left.Dimension,
      Elements => new Aggregates(1 .. Left.Dimension));
  begin
    for Index in 1 .. Left.Dimension loop
       Result.Elements(Index) := Left.Elements(Index) + 
         Right.Elements(Index);
    end loop;
    return Result; -- At this point, previous storage allocated
                   -- to the result object becomes inaccessible.
  end "+";

If your Ada run-time system happens to support automatic garbage 
collection, then fine.  Otherwise, get ready for Storage_Error soner or 
later!  Let's suppose we want to use in-place computation to save space 
and speed.  Let's try:

  X := X + Y;

Unfortunately, this does not give in-place computation, since after the 
assignment X will be "pointing" to a whole new structure, and the 
previous structure will be inaccessible.  What we seem to need is a way 
of "getting at" the thing which is the function result.  

The cure mignt be something along the lines of a new attribute 'Result, 
which would apply to a function, and act like an "in out" procedural 
parameter:

  function "+"(Left, Right: in Vectors) return Vectors is
  begin
    ...
    for Index in 1 .. Left.Dimension loop
      "+"'Result.Elements(Index) := Left.Elements(Index) + 
        Right.Elements(Index);
    end loop;
  end;

This would cure the problems of non-deallocation of space, and allow 
in-place computation to take place.  Also, it does not mess with the 
":=" operator.  However, what do we "return"?  Also, what is the 
'Result in cascaded operations such as X := A + B + C; ?

Alternatively, the language rules could be re-defined to allow 
operator names to be procedures with a single "out" or "in out" 
procedure.

  procedure "+"(Left, Right: in Vectors; Result: in out Vectors);

giving equivalently:

  "+"(Left => A, Right => B, Result => X);
  X := A + B;

and we could do away with the reserved word "function" completely.

Comments, flames, problems?

Simon Tuffs
Tuffs@Alcoa.Com

             reply	other threads:[~1988-12-06 13:05 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1988-12-06 13:05 TUFFS1 [this message]
1988-12-14 18:05 ` Assignment Overloading William Thomas Wolfe,2847,
replies disabled

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