Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!swrinde!ucsd!ogccse!blake!unicorn!n8243274
From: n8243274@unicorn.WWU.EDU (steven l. odegard)
Newsgroups: comp.lang.modula2
Subject: Overloading Operators: Extension to Language
Summary: Proposed syntax
Keywords: Overload
Message-ID: <226@unicorn.WWU.EDU>
Date: 3 Oct 89 02:27:52 GMT
Reply-To: n8243274@unicorn.UUCP (steven l. odegard)
Organization: Western Washington Univ, Bellingham, WA
Lines: 150

In article  Modula2 List 
 writes:
[stuff delted]
>    Which (algebraically) reads exactly as you mean it.  In Ada you can
>  define the '+' operator to be able to handle the Complex number type.
>
>    Would such a feature be warranted in Modula-2?
>    Here is some theoretical code:
[stuff deleted]

  May I add my two cents worth to the all desired extensions for a better
future language inspired by Wirth's ingenious Modula-2:

  In addition to IMPORT and EXPORT, modified modula programs will have
optional INHERIT and EXHIBIT.  These, unlike IMPORT and EXPORT, refer to
modifications to the language itself.  The syntax for INHERIT and EXHIBIT is
similar to that for IMPORT and EXPORT.

  If operator overloading is to be defined in the current module, i.e. not
INHERITed, then first define the procedure and its associated types:

    IMPLEMENTATION MODULE InternalComplexUseage ;

    TYPE Complex = RECORD RP, CP : REAL END ;
    PROCEDURE AddComplex( A, B : Complex ;  VAR R : Complex ) ;
    BEGIN R.RP := A.RP + B.RP ;  R.CP := A.CP + B.CP END AddComplex ;

  Now, overload it to the operator "+".  This shall be accomplished by a new
block option with the header QUALIFIED.  We'll assume here some other operators
have also been defined for Complex: 

    QUALIFIED complexad ;
      AddComplex( A, B : Complex ;  VAR R : Complex ) FOR R := A + B ;
      SubComplex( A, B : Complex ;  VAR R : Complex ) FOR R := A - B ;
      MulComplex( A, B : Complex ;  VAR R : Complex ) FOR R := A * B ;
      DivComplex( A, B : Complex ;  VAR R : Complex ) FOR R := A / B ;
      CopyComplex( A : Complex ;  VAR R : Complex ) FOR R := A ;
    END complexad ;

    (* ... body omitted *)

    END InternalComplexUseage .

  The compiler will now recognize A+B where A and B are Complex, and substitute
the appropriate calls.  It will also recognize and decompose objects 
like A*(B+C) + C/(A+B) .

  Now, if these objects are desired to be used elsewhere, then they must
(1) be EXHIBITed from the current module, and (2) INHERITed into the module
desired.  An INHERITance will automatically import its subsiderary objects.

    DEFINITION MODULE ComplexDefinitions ;
      
    EXPORT Complex, AddComplex, SubComplex, MulComplex, DivComplex ;
    EXHIBIT complexad ;

    (* ... definition body omitted, it is as in InternalComplexUseage *)
    END ComplexDefinitions .

    (* ... within another module now ... *)
    MODULE UseComplexDefinitions ;

    FROM ComplexDefinitions INHERIT complexad ; (* automatically imports 
	|* Complex, AddComplex, etc.;  overloads "+", "-", "*", etc. *)

    (* ... body omitted *)

    END UseComplexDefinitions .

Another example, building on the abstract type defined:

    IMPLEMENTATION MODULE MatrixDefinitions ;
    FROM ComplexDefinitions INHERIT complexad ;  (* this statement also IMPORTS
	|* Complex, AddComplex, etc. *)

    CONST NodeSize = 31 ;
    TYPE Matrix = POINTER TO MatrixListHead ;
    MatrixListHead = RECORD
      Dimensions : RECORD
	Rows, Columns : CARDINAL ;
	ChainNumber : CARDINAL ;
	Current : ARRAY [ 0 .. NodeSize ] OF Complex ;
	Next : MatrixListHead ;
      END ;

    PROCEDURE AddMatrix( A, B : Matrix ;  VAR R : Matrix ) ;
    (* ... body is deleted. *)

    PROCEDURE SubMatrix( A, B : Matrix ;  VAR R : Matrix ) ;
    (* ... body is delted. *)

    END MatrixDefinitions .

Now, its corresponding definition module is:

    DEFINITION MODULE MatrixDefinitions ;
    EXHIBIT QUALIFIED matrixad ; (* perhaps, like EXPORT QUALIFIED, these need
	|* not be included in a DEFINITION module. *)

    TYPE Matrix ; (* hidden *)
    PROCEDURE AddMatrix( A, B : Matrix ;  VAR R : Matrix ) ;
    PROCEDURE SubMatrix( A, B : Matrix ;  VAR R : Matrix ) ;
    PROCEDURE MulMatrix( A, B : Matrix ;  VAR R : Matrix ) ;
    PROCEDURE CopyMatrix( A : Matrix ;  VAR R : Matrix ) ;

    QUALIFIED matrixad ;
      AddMatrix( A, B : Matrix ;  VAR R : Matrix ) FOR R := A + B ;
      SubMatrix( A, B : Matrix ;  VAR R : Matrix ) FOR R := A - B ;
      MulMatrix( A, B : Matrix ;  VAR R : Matrix ) FOR R := A * B ;
      CopyMatrix( A : Matrix ;  VAR R : Matrix ) FOR R := A ;
    END matrixad ;

    END MatrixDefinitions .

In the same article, we have the proposed body section:
>VAR
>  Result : Complex;
>  A, B   : Complex;
>
>BEGIN
>  A := 2.0, 2.0;
>  B := 4.0, 4.0;
>  Result := A + B;
>END;

Here presupposed is the use of structured constants.  Like SETs, these
should be prefixed with the appropriate structure's name.  We require a new
form of bracket delimiter indicating this, perhaps <# and #> .  Now, then,
here is how this should appear:

  PROCEDURE DefineComplex( A, B : REAL ;  VAR C : Complex ) ;

  QUALIFIED Complexad ;
    DefineComplex( A, B : REAL ;  VAR C : Complex )
      FOR C := Complex <# A, B #> ;
  END Complexad ;

Then the body section appears
  VAR
    Result : Complex;
    A, B   : Complex;
  
  BEGIN
    A := Complex <# 2.0, 2.0 #> ;
    B := Complex <# 4.0, 4.0 #> ;
    Result := A + B;
  END;

I don't propose defining user-defined infix operators at this time.
--SLO