GENERIC TYPE IN MODULA-2 
Author Message
 GENERIC TYPE IN MODULA-2

I'm looking for a simple way to create ageneric type in Modula-2...  My
problem is simple...  I wrote a library of "binary tree procedures" and
nodes structure look like this:

TYPE
  Node = RECORD
           Info: Element_Type;
           Left: Ptr_Node;
           Right:Ptr_Node;
         END;

My problem is that I have 2 different "Info" to work with and I am not
interested to create a second library for something that's already
coded!!  In simple words, look at this example:

PROCEDURE Find_Key(Searched_Key:CARDINAL;Current_Key:CARDINAL);

Now, here's my problem...  I have to work with 2 types of Info:

Info #1

 Student = RECORD
            FirstName:STRING;
            LastName:STRING;
            Age:CARDINAL;
            Address:STRING;
            DateOfBirth: Date_Type;
           END;

Info #2
 Courses = RECORD
            Course:STRING;
            Credits: CARDINAL;
            Place:STRING;
           END;

So, I have to specify the type of Info in my procedures and, since I got
2, this is impossible...  I found (in a book) a complex way to create a
generic type at the byte level (with stacks...) but my teacher will
never believe I coded this by myself!!! (I do not reproduce what I
do not fully understand...).  The question is:  Do you know a SIMPLE way
of making a generic type...

 * SLMR 2.1a * He's dead, Jim.

--  
uucp: uunet!m2xenix!puddle!167!159!Benoit.St-jean



Fri, 12 May 1995 20:51:11 GMT  
 GENERIC TYPE IN MODULA-2

Quote:
> I'm looking for a simple way to create ageneric type in Modula-2...  My
> problem is simple...  I wrote a library of "binary tree procedures" and
> nodes structure look like this:

> TYPE
>   Node = RECORD
>            Info: Element_Type;
>            Left: Ptr_Node;
>            Right:Ptr_Node;
>          END;

> My problem is that I have 2 different "Info" to work with and I am not
> interested to create a second library for something that's already
> coded!!  In simple words, look at this example:

My preferred approach to this is to separate the access structure
from the data, i.e. you don't build a tree of data, you build a
tree of pointers to data.  For your example, this means defining

    TYPE Node = RECORD
                    info: ADDRESS;
                    Left, Right: Ptr_Node;
                END (*RECORD*);

and the remaining details are obvious.  Of course your module must
include appropriate CreateTree and DeleteTree operations.

Using pure Modula-2, there isn't really any good way to get around
using type ADDRESS for this sort of problem (unless you use records
with variants, and I've always regarded that as a kludgey solution in
any language).  In my own work I don't mind doing this, on the grounds
that the "generic data type" modules are down near the bottom of the
module dependency tree, where the end user is unlikely to have to
deal with them.  (When writing the modules which actually manipulate
data, you don't have to know any of the internal details of the
"binary trees" module.)  Nevertheless this solution will bother some people.

This is one of the few situations where object-oriented extensions
to the language are worth considering.

--



Fri, 19 May 1995 08:44:35 GMT  
 GENERIC TYPE IN MODULA-2

 >I'm looking for a simple way to create ageneric type in Modula-2...  My
 >problem is simple...  I wrote a library of "binary tree procedures" and
 >nodes structure look like this:

Handling generics is awkward.  The low-level approaches (SYSTEM.ADDRESS and
SYSTEM.WORD) are messy and error prone.

A simpler approach for re-engineering with minimum fuss (although you have to
recompile) is suggested below.  This is a specimen solution given to one of my
classes a few years back.  It should make sense, i hope.

Define yourself an ItemHandler module that exports your information type
and the operations that you need on it.  Here's an example

DEFINITION MODULE ItemHandler;
(* Simple definition of an ITEMS type and simple operations on it for use
   with exploring the use of the Tree library
   P.D. Terry, Rhodes University, 13 August 1989 *)

  FROM EasyInOut IMPORT STRING;

  TYPE
    ITEMS = RECORD
              Quantity : CARDINAL;
              ItemName : STRING;
            END;

  PROCEDURE ReadItem (VAR Item : ITEMS);
  (* Read the details of an Item from the input file *)

  PROCEDURE WriteItem (VAR Item : ITEMS);
  (* Display the details of an Item on the output file *)

  PROCEDURE Encode (VAR Item : ITEMS; Number : CARDINAL; Name : STRING);
  (* Construct an Item from its number and name *)

  PROCEDURE Decode (Item : ITEMS; VAR Number : CARDINAL; VAR Name : STRING);
  (* Extract the Number and Name details for an Item *)

  PROCEDURE CompareItem (Item1, Item2 : ITEMS) : INTEGER;
  (* Return -1 0 +1 as Item1 < = > Item2 (based on case insensitive names *)

END ItemHandler.

The implementation might be something like

IMPLEMENTATION MODULE ItemHandler;
(* Simple definition of an ITEMS type and simple operations on it for use
   with exploring the use of the ListHandler library
   For details see corresponding Definition Module
   P.D. Terry, Rhodes University, 13 August 1989 *)

  FROM EasyInOut IMPORT STRING, ReadCard, WriteCard, Prompt, ReadString,
                        WriteString, WriteStringLeft, Write, SkipSpaces,
                        ReadLn, WriteLn;
  FROM Strings   IMPORT CompareStr, Length;

(*
  TYPE
    ITEMS = RECORD
              Quantity : CARDINAL;
              ItemName : STRING;
            END;
*)

  PROCEDURE ReadItem (VAR Item : ITEMS);
    BEGIN
      WITH Item DO
        Prompt('Quantity? '); ReadCard(Quantity);
        Prompt('Product? '); SkipSpaces; ReadString(ItemName)
      END;
      ReadLn;
    END ReadItem;

  PROCEDURE WriteItem (VAR Item : ITEMS);
    BEGIN
      WITH Item DO
        WriteCard(Quantity, 6); Write(' ');
        WriteStringLeft(ItemName, 25);
        WriteLn
      END
    END WriteItem;

  PROCEDURE Encode (VAR Item : ITEMS; Number : CARDINAL; Name : STRING);
    BEGIN
      Item.ItemName := Name;
      Item.Quantity := Number
    END Encode;

  PROCEDURE Decode (Item : ITEMS; VAR Number : CARDINAL; VAR Name : STRING);
    BEGIN
      Name := Item.ItemName;
      Number := Item.Quantity
    END Decode;

  PROCEDURE CompareItem (Item1, Item2 : ITEMS) : INTEGER;

    PROCEDURE Capitalise (VAR String : STRING);
    (* Change String into UPPER CASE equivalent *)
      VAR
        I : CARDINAL;
      BEGIN
        FOR I := 0 TO Length(String) DO String[I] := CAP(String[I]) END
      END Capitalise;

    BEGIN
      Capitalise(Item1.ItemName); Capitalise(Item2.ItemName);
      RETURN CompareStr(Item1.ItemName, Item2.ItemName)
    END CompareItem;

END ItemHandler.

Then code your tree handler or whatever a bit like what you see below.  I have

 given two versions - one opaque and the other not.

When you initiate a tree you then effectively bind in the actions you need.
Here is a sample main program

MODULE Prac19;
(* Sample test bed program for TreeHandler
   P.D. Terry, Rhodes University, 21 August 1989 *)

  FROM ItemHandler IMPORT ITEMS, ReadItem, WriteItem, CompareItem;

  FROM TreeHandler IMPORT TREES, NewTree, AddItem, WalkTreeInOrder,
                          WalkTreeInPreOrder, DeleteItem, ModifyItem;
  FROM EasyInOut   IMPORT NoMoreData, WriteLn, WriteString, FileInput;

  VAR
    MyTree : TREES;
    Successful : BOOLEAN;
    MyItem, LastItem : ITEMS;

  PROCEDURE There(VAR Item : ITEMS);
    BEGIN
      WriteString('There'); WriteItem(Item);
      Item.Quantity := 0;
    END There;

  PROCEDURE NotThere(VAR Item : ITEMS);
    BEGIN
      WriteString('NotThere'); WriteItem(Item);
    END NotThere;

  BEGIN (*TreeDemo*)
    FileInput;
    NewTree(MyTree, CompareItem);
    LOOP (*building tree*)
      ReadItem(MyItem);
      IF MyItem.Quantity = 0 THEN EXIT END;
      AddItem(MyItem, MyTree);
      LastItem := MyItem;
    END;
    WriteLn;
    LOOP (*modifying tree*)
      ReadItem(MyItem);
      IF MyItem.Quantity = 0 THEN EXIT END;
      ModifyItem(MyItem, MyTree, There, NotThere);
    END;
    WalkTreeInOrder(MyTree, WriteItem);
    LOOP
      ReadItem(LastItem);
      IF NoMoreData THEN EXIT END;
      DeleteItem(LastItem, MyTree, Successful);
      WalkTreeInOrder(MyTree, WriteItem);
    END;
    WriteLn;
    WalkTreeInOrder(MyTree, WriteItem);
  END Prac19.

------------

DEFINITION MODULE TreeHandler;
(* Facilities for creating and handling binary search trees of items
   P.D. Terry, August 1989,  Release 2.0  for ITEMS from ItemHandler. *)

  FROM ItemHandler IMPORT ITEMS;

  TYPE
    TREES;

    HANDLER = PROCEDURE(VAR ITEMS);
    COMPAREPROC = PROCEDURE (ITEMS, ITEMS) : INTEGER;

  PROCEDURE NewTree (VAR Tree : TREES; Ordering : COMPAREPROC);
  (* Create an empty 'Tree' and assign it an 'Ordering' relation *)

  PROCEDURE DeleteItem (ThisItem : ITEMS; VAR Tree : TREES;
                        VAR Successful : BOOLEAN);
  (* Look for 'ThisItem' in 'Tree' and if 'Successful' then delete it *)

  PROCEDURE AddItem (ThisItem : ITEMS; VAR Tree : TREES);
  (* Add 'ThisItem' in order to a 'Tree' of items *)

  PROCEDURE ModifyItem (ThisItem : ITEMS; Tree : TREES;
                        There, NotThere : HANDLER);
  (* Search for 'Item' in 'Tree' and take appropriate action depending
     on whether it is 'There' or 'NotThere' *)

  PROCEDURE WalkTreeInOrder (Tree : TREES; Process : HANDLER);
  (* 'Process' each item in entire 'Tree' in order *)

  PROCEDURE WalkTreeInPreOrder (Tree : TREES; Process : HANDLER);
  (* 'Process' each item in entire 'Tree' in "preorder" order *)

  PROCEDURE Replace (Tree : TREES; OldItem : ITEMS; NewItem : ITEMS;
                     VAR Successful : BOOLEAN);
  (* If 'Successful', then 'OldItem' in 'Tree' will have been updated to
     'NewItem'.  'OldItem' is located by the key field used in the
     ordering relation for the 'Tree' *)

  PROCEDURE Retrieve (Tree : TREES; FindItem : ITEMS; VAR ThisItem : ITEMS;
                     VAR Successful : BOOLEAN);
  (* If 'Successful', then 'FindItem' in 'Tree' will have been located
     using the key field used for the ordering relation for the 'Tree',
     and 'ThisItem' will be returned as the item located *)

END TreeHandler.

---------

IMPLEMENTATION MODULE TreeHandler;
(* Facilities for creating and handling binary search trees of items
   P.D. Terry, August 1989,  Release 2.0  for ITEMS from ItemHandler
   For details see corresponding definition module *)

  FROM ItemHandler IMPORT ITEMS;
  FROM Storage     IMPORT ALLOCATE, DEALLOCATE;
  FROM EasyInOut IMPORT WriteString, WriteCard, WriteLn, WriteBool;

(*
  TYPE
    HANDLER = PROCEDURE(VAR ITEMS);
    COMPAREPROC = PROCEDURE (ITEMS, ITEMS) : INTEGER;
   *)
  TYPE
    LINKS = POINTER TO NODES;
    TREES = POINTER TO TREEDETAILS;
    TREEDETAILS = RECORD
                    Root : LINKS;
                    CompareItem : COMPAREPROC;
                  END (*TREEDETAILS*);
    NODES = RECORD
              Item : ITEMS;
              LeftTree, RightTree : LINKS;
            END (*NODES*);

  PROCEDURE NewTree (VAR Tree : TREES; Ordering : COMPAREPROC);
    BEGIN
      ALLOCATE(Tree, SIZE(TREEDETAILS));
      Tree^.Root := NIL; Tree^.CompareItem := Ordering
    END NewTree;

  PROCEDURE FindLink (ThisItem : ITEMS; Tree : TREES) : LINKS;
  (* Find the link, if any, pointing to 'ThisItem' in a 'Tree' *)

    PROCEDURE GetLink (Root : LINKS) : LINKS;
      BEGIN
        IF Root = NIL
          THEN
            RETURN NIL
          ELSE
            CASE Tree^.CompareItem(ThisItem, Root^.Item) OF
              -1 : RETURN GetLink(Root^.LeftTree)
          |   0  : RETURN Root
          |   +1 : RETURN GetLink(Root^.RightTree)
            END
        END
      END GetLink;

    BEGIN
      RETURN GetLink(Tree^.Root)
    END FindLink;

  PROCEDURE DeleteItem (ThisItem : ITEMS; VAR Tree : TREES;
                        VAR Successful : BOOLEAN);

    PROCEDURE DeleteFromTree (VAR Current : LINKS);
      VAR
        SafeLink : LINKS;

      PROCEDURE SubstituteGreatest (VAR Here : LINKS);
        BEGIN
          IF Here^.RightTree <> NIL
            THEN
              SubstituteGreatest(Here^.RightTree)
            ELSE
              Current^.Item := Here^.Item;
              SafeLink := Here;
              Here := Here^.LeftTree
          END
        END SubstituteGreatest;

      BEGIN
        IF Current = NIL
          THEN
            Successful := FALSE
          ELSE
            CASE Tree^.CompareItem(ThisItem, Current^.Item) OF
                -1 : DeleteFromTree(Current^.LeftTree)
            |   +1 : DeleteFromTree(Current^.RightTree)
            |   0  : (*found*)
                     SafeLink := Current; Successful := TRUE;
                     IF Current^.RightTree = NIL
                       THEN Current := Current^.LeftTree;
                       ELSIF Current^.LeftTree = NIL
                         THEN Current := Current^.RightTree;
                         ELSE SubstituteGreatest(Current^.LeftTree);
                     END;
                     DEALLOCATE(SafeLink, SIZE(NODES))
...

read more »



Sat, 20 May 1995 15:06:23 GMT  
 GENERIC TYPE IN MODULA-2

#
# I'm looking for a simple way to create ageneric type in Modula-2...  My
# problem is simple...  I wrote a library of "binary tree procedures" and
# nodes structure look like this:

  [ecamples deleted -- dcs]

# So, I have to specify the type of Info in my procedures and, since I got
# 2, this is impossible...  I found (in a book) a complex way to create a
# generic type at the byte level (with stacks...) but my teacher will
# never believe I coded this by myself!!! (I do not reproduce what I
# do not fully understand...).  The question is:  Do you know a SIMPLE way
# of making a generic type...

  The way I handled this problem in making a generic linked-list
  package was to produce a container object:

  TYPE
    LLptr       = POINTER TO LLobject;
    LLobject    = RECORD
      ObSize    : CARDINAL;
      Lptr,
      Rptr      : LLptr;
      END (*  LLobject *);

  Then hid the low-level garf in a few procedures in the package.
  Obviously, two of the procedures were to allocate & deallocate
  LLobjects, and required the appropriate size to make it work.

  Sorting simply required that a procedure be passed in to
  compare the contents of the list.

--- D. C. Sessions                            Speaking for myself ---

--- Author (and everything else!) of TMail  (DOS mail/news shell) ---



Wed, 19 May 1993 21:42:00 GMT  
 GENERIC TYPE IN MODULA-2


Quote:


>  >I'm looking for a simple way to create ageneric type in Modula-2...  My
>  >problem is simple...  I wrote a library of "binary tree procedures" and
>  >nodes structure look like this:

> Handling generics is awkward.  The low-level approaches (SYSTEM.ADDRESS and
> SYSTEM.WORD) are messy and error prone.

> A simpler approach for re-engineering with minimum fuss (although you have to
> recompile) is suggested below.  This is a specimen solution given to one of my
> classes a few years back.  It should make sense, i hope.

> Define yourself an ItemHandler module that exports your information type
> and the operations that you need on it.  Here's an example

>     [...]

This solution works when there is just one information type, but a
more typical situation - and, if I remember correctly, the problem
posed by the original poster - is where there are several different
information types.  For example you might have a tree of integers,
a tree of reals, a tree of characters, etc.,  _all coexisting in the
same program_.  In this case Pat's solution would have to be modified
so that the basic "item" type was either a variant record type, or
was referred to via something like ADDRESS.

I dislike the variant record approach because it requires the "trees"
module to import from the "items" module or (more likely) modules.
If we make a distinction between the concepts "data" and "ways to
organise data", then in a very large number of applications the
"data" are the things which are of primary interest to the programmer,
whereas the "ways to organise data" (such as keeping them in trees,
keeping them in a linear list structure, etc.) are lower-level
things which ought be provided in some sort of standard library.
The applications programmer might well be the most appropriate
person to decide that a binary tree is a good choice for storing
the data, but he or she should not be forced to re-invent the wheel
by having to work out how to implement a binary tree.  (The problem
is not too tricky for binary trees, for which solutions can be copied
from any of a great variety of textbooks; but think of the more
abstruse data structures whose internal details are understood only
by computer scientists.)

If one accepts the above viewpoint, then logically the "trees"
module belongs at a lower level in the module hierarchy than the
"items" modules.  This rules out any solution which requires the
"trees" module to import the definitions of the item types.
An OO approach can get us around this problem, but M2 does not
(so far) support class inheritance.  In the meantime, solutions
using ADDRESS seem to provide the simplest resolution of the problem.

(By the way, I've never agreed with Wirth's decision to put ADDRESS
into module SYSTEM.  It's perfectly portable from one machine to
another.)

Admittedly ADDRESS has the fault that its use weakens type-checking;
but this becomes less of a problem when it is used in low-level
library modules whose internal details remain hidden to the
applications programmer.

--



Mon, 22 May 1995 12:45:51 GMT  
 GENERIC TYPE IN MODULA-2

Quote:
>From demos!L-usenet%kremvax.hq.demos.su Tue Dec  1 14:52:49 MSK 1992

>Newsgroups: comp.lang.modula2
>Subject: [NEWS] GENERIC TYPE IN MODULA-2

>Date: 23 Nov 92 12:51:11 GMT
>Article-I.D.: puddle.24310.2B169F11
>Organization: FidoNet node 1:167/159 - XON/XOFF Informatio, Montreal QC
>Status: O

>I'm looking for a simple way to create ageneric type in Modula-2...  My
>problem is simple...  I wrote a library of "binary tree procedures" and
>nodes structure look like this:

>TYPE
>  Node = RECORD
>           Info: Element_Type;
>           Left: Ptr_Node;
>           Right:Ptr_Node;
>         END;

>My problem is that I have 2 different "Info" to work with and I am not
>interested to create a second library for something that's already
>coded!!  In simple words, look at this example:

[stuff deleted]

Quote:
>--
>uucp: uunet!m2xenix!puddle!167!159!Benoit.St-jean


I guest, the only solution is

TYPE Element_Type = ADDRESS; (* ;-) *)

There was a demo prog in JPI Modula-2 v1.15 (sic!) about BTree.
It was a full prog with example of such approach. Another one can
be found in QSort procedure source. NB! The item comparision, etc,
must be done by "foreign" routines, when the library itself just
maintain BTree ops.

best regards
jno
--
Eugene V. Dvurechenski                     (-: -------------- :-)  __ __
Grif-01, ltd, technical advisor             |   DON'T  WORRY!  |   -o o-

voice : +7(095) 250-57-62                  (-: -------------- :-)   \_/



Sat, 20 May 1995 21:41:32 GMT  
 GENERIC TYPE IN MODULA-2

   If one accepts the above viewpoint, then logically the "trees"
   module belongs at a lower level in the module hierarchy than the
   "items" modules.  This rules out any solution which requires the
   "trees" module to import the definitions of the item types.
   An OO approach can get us around this problem,

How?  For the sake of a concrete example, how would it enable to me to
have a tree of INTEGERs and a tree of REALs?

bevan



Tue, 23 May 1995 04:53:07 GMT  
 GENERIC TYPE IN MODULA-2

Quote:

>    If one accepts the above viewpoint, then logically the "trees"
>    module belongs at a lower level in the module hierarchy than the
>    "items" modules.  This rules out any solution which requires the
>    "trees" module to import the definitions of the item types.
>    An OO approach can get us around this problem,

> How?  For the sake of a concrete example, how would it enable to me to
> have a tree of INTEGERs and a tree of REALs?

I'm sticking my neck out a little here, because I'm not an OO
enthusiast (I prefer top-down design) and don't use it.  However
as I see it the idea would be

1. Define a base class BinaryTree, which just has the left and
   right pointers but no data.
2. Then define a class IntegerTree, which inherits the tree structure
   from BinaryTree, but adds a data field to hold a integer.
3. Similarly, define RealTree which inherits from BinaryTree.

If you want operations like tree traversal, then you need something
to compare elements.  I guess the way to do this is to have a
comparison procedure in the base class which simply causes an
"illegal comparison" exception, and then override this with comparison
procedures in the derived classes.  The traversal procedures can
still go down in the base class, but they would call comparison
functions which are, in fact, supplied from the derived classes.

I don't yet have strong opinions on whether this is a good or bad
design.  (The way I do this sort of work in my own programming is
just to use type ADDRESS, and ignore the OO approaches.)

--



Fri, 26 May 1995 13:04:19 GMT  
 GENERIC TYPE IN MODULA-2



   >    An OO approach can get us around this problem,
   >
   > How?  For the sake of a concrete example, how would it enable to me to
   > have a tree of INTEGERs and a tree of REALs?

   [ define base class BinaryTree and then subclass it to create
     IntegerTree and RealTree ]

   I don't yet have strong opinions on whether this is a good or bad
   design.

If the inheritance was private (to use a C++ term) then I could live
with it, but I think it is a case of using the wrong tool for the job.
To me this problem is crying out for some form parameterisable
structure (e.g. ML style signatures/structures or Ada generics).

  (The way I do this sort of work in my own programming is
   just to use type ADDRESS, and ignore the OO approaches.)

That is exactly what I do in languages that don't support some form of
parameterisable structure, but IMHO it is rather tedious.

bevan



Sat, 27 May 1995 06:51:57 GMT  
 GENERIC TYPE IN MODULA-2
TYPE
   data :ADDRESS;
   left, right :Pointer;

Unfortunately that approach removes type checking and you can put the wrong
data type into your tree. But then again it allows you to build a tree of
non-homogeneous items if you want to.

To still be a modulan i've come to the conclusion that maybe a tree procedure
should import the type of item that you want. It doesn't make the tree
module useful as a generic library tool, but it does allow you to re-use
the code -you only need to re-compile it as part of the current project.
  Having more than one tree is a problem though.

Yes it looks like the OO approach wins in a situation like this.

And yes, procedures should be passed into the tree module to do the
comparisons.

John Andrea



Tue, 30 May 1995 05:39:54 GMT  
 GENERIC TYPE IN MODULA-2

Quote:
>Peter Moylan writes:
>Admittedly ADDRESS has the fault that its use weakens type-checking;
>but this becomes less of a problem when it is used in low-level
>library modules whose internal details remain hidden to the
>applications programmer.

But hiding addresses doesn't make it less of a problem.

Consider the same problem, a tree of integers and a tree of reals
in the same applications. It would go something like this

FROM BinTree IMPORT Tree, Create, Put, Get;

VAR
  int_tree, real_tree :Tree;
  i :INTEGER;
  x :REAL;

BEGIN
   Create( int_tree );
   Create( real_tree );

   Put( int_tree, 1 );   Put( int_tree, 2 );

   Put( real_tree, 5.5 );  Put( real_tree, 4.2 );

   ...other stuff...

   Get( int_tree, i ); Get( int_tree, i ); Get( real_tree, i );

OOPS - programmer typo, that should have been "Get( real_tree, x )"
but is will compile ok, and the tree module will happily pass back
something unwanted.

If the programmer knows that this sort of error is likely then another
layer is required.

   Procedure CreateIntTree;
   BEGIN
      Create( int_tree );
   END IntTree;
   Procedure PutIntTree( i :INTEGER );
   BEGIN
     Put( int_tree, i );
   END PutIntTree;

    ....same for the get and real tree procedures...

BEGIN
   CreateIntTree;
   GreateRealTree;

   PutInt( 1 ); PutInt( 2 );
   PutReal( 5.5 ); Put( 4.2 );

   GetInt( i ); GetInt( i ); GetInt( x );
                                     ^type mismatch

Error caught at compile time. But it does require more work on the programmers
part and the forthought about the impact of typos.

John Andrea



Wed, 31 May 1995 00:03:29 GMT  
 GENERIC TYPE IN MODULA-2

   TYPE
      data :ADDRESS;
      left, right :Pointer;

   Unfortunately that approach removes type checking and you can put the wrong
   data type into your tree.

Not if you create a separate module where the parameters have the
correct type and must be coerced to the above.  Granted you could get
this wrong, but if you do it once, you can use it as a template and
then just use search/replace to create a new module with the correct
type.  If the compiler is any good, it should be able to inline all
the interface procedures and so it doesn't cost you anything at
runtime.

   Yes it looks like the OO approach wins in a situation like this.

The one OO solution I've seen to this is not one I'd advocate and not
one I think comp.object readers would like either.  The classic (and
IMHO still the best) solution to this problem is parametric
polymorphism aka ``generics'' in Ada or ``templates'' in C++ (the
above solution is just a manual instantiation method).  This has
_nothing_ to do with OO.

yours against gratuitous use of OO as a panacea,

bevan



Sat, 03 Jun 1995 04:53:14 GMT  
 GENERIC TYPE IN MODULA-2

  I wrote
  >Unfortunately that approach removes type checking and you can put the wrong
  >data type into your tree.

  bevan replied
  >Not if you create a separate module where the parameters have the
  >correct type and must be coerced to the above.

But how many types could you have that you would want to have in a tree.
All the cards, ints, reals, chars, arrays of cards, arrays of chars,
records with a card and a sting, records with a string and a real, records
with two strings, ..... Quite a large variety, would you want to have a
module for every type.

  bevan also replied
  >Granted you could get this wrong, but if you do it once, you can use
  >it as a template and then just use search/replace to create a new
  >module with the correct type.  If the compiler is any good, it should
  >be able to inline all the interface procedures and so it doesn't cost
  >you anything at runtime.

Templates. Yes thats the way i do it. I don't use generic tree modules like
that as a pre-compiled library but i get the source code, make a part of the
current project and compile it as part of the current project.
  Its less useful that a true library module, but it does allow for code
reuse with no modifications so chances are that it works correctly.

John Andrea



Sat, 03 Jun 1995 23:15:45 GMT  
 
 [ 13 post ] 

 Relevant Pages 

1. Tagged Types as Generic Formal Parameters (was comparison in generic packages)

2. Generic Modula-2 proposal

3. Generic Modula Compiler?

4. Generic Lists in Modula-2

5. Generic Lists in Modula-2

6. SRNC-ST 3.2: Generic Types

7. Once-function with type derived from formal generic

8. creation of generic types

9. Type declarations and generic classes in CLOS - HOW??

10. Problem with Create on entity of constrained generic type

11. Generic types.

12. Generic data type?

 

 
Powered by phpBB® Forum Software