[comp.lang.modula3] Specializing objects

nr@hart.Princeton.EDU (Norman Ramsey) (02/15/91)

Suppose I have two object types

TYPE
  T = OBJECT
        mumble, fritz: INTEGER;
      END;

  TA = T OBJECT
         a: BOOLEAN;
       END;

and suppose further that I am handed a T and want to produce a TA with
the property that every field of the TA has the same value it had in
the T.  I can't think of anything any better than:

PROCEDURE Narrow(o:T):TA =
BEGIN
  RETURN NEW(TA, mumble := o.mumble, fritz := o.fritz, a := <whatever>);
END Narrow;

Is there some way for me to do this without having to enumerate all
the fields of T?  If not, I am bound to break my programs by extending
T and forgetting to update Narrow.
--
Norman Ramsey
nr@princeton.edu

muller@src.dec.com (Eric Muller) (02/15/91)

In article <6929@rossignol.Princeton.EDU>, nr@hart.Princeton.EDU (Norman Ramsey) asks:
> 
> Suppose I have two object types
> 
> TYPE
>   T = OBJECT
>         mumble, fritz: INTEGER;
>       END;
> 
>   TA = T OBJECT
>          a: BOOLEAN;
>        END;
> 
> and suppose further that I am handed a T and want to produce a TA with
> the property that every field of the TA has the same value it had in
> the T.  I can't think of anything any better than:
> 
> PROCEDURE Narrow(o:T):TA =
> BEGIN
>   RETURN NEW(TA, mumble := o.mumble, fritz := o.fritz, a := <whatever>);
> END Narrow;
> 
> Is there some way for me to do this without having to enumerate all
> the fields of T?  If not, I am bound to break my programs by extending
> T and forgetting to update Narrow.

Given that RTHeap has a Duplicate procedure:

	PROCEDURE Duplicate (r: REFANY): REFANY;
	(* return a reference to a new allocated copy of the referent, not
	   recursively applied to internal references.  Duplicate(r) is
	   equivalent to Allocate (TYPECODE (r)).  *)

I could provide:

	PROCEDURE ?? (r1, r2: ROOT): ROOT;
	(* The type of r1 must be a subtype of the type of r2. 
           The fields of r2 are (non-recursively) copied to the
           corresponding  fields of r1 *)

You could write:

	oa := ?? (NEW (TA, a = <whatever>), o);

Opinions ?

eric.