[net.lang.ada] BITNET mail follows

EBEL@CLSEPF51.BITNET (06/11/86)

Problems with abstract data types packages when trying to unify them for
subranges and access structures.


     In writing abstract data types packages, we define a set of operators for
structures build from a generic parameter ITEM_TYPE. In this case we want to
have the generic formal parameter ITEM_TYPE of limited type because it is more
general and allows one to instantiate the package with any type. The client
must then furnish a procedure ASSIGN (and a function "=") which we use for
implementing the package. We then offer the expected operators and in combining
these packages the user can build combinations of abstract data types, for
instance queues of stacks, of sets or even of queues.

     Example:

     generic
       type ITEM_TYPE is limited private;
       with procedure ASSIGN (DESTINATION : out ITEM_TYPE;
                              SOURCE      : in ITEM_TYPE) is <>;
       with function "=" (LEFT, RIGHT : ITEM_TYPE) return BOOLEAN is <>;

     package QUEUE_G is

       type QUEUE_TYPE is limited private;
       procedure INSERT (QUEUE : in out QUEUE_TYPE ; ITEM : in ITEM_TYPE);
       ...

     private
       type CELL;
       type LINK is access CELL;
       type CELL is
         record
           DATA: ITEM_TYPE;
           NEXT: LINK;
         end record;
       type QUEUE_TYPE is
         record
           FIRST, LAST: LINK;
           COUNT: NATURAL := 0;
         end record;
     end QUEUE_G;

the procedure ASSIGN furnished by the user has the usual semantics

     DESTINATION := SOURCE;

     The first problem arises with data structures pointed by access. Any
reference to an old structure is lost when using this procedure ASSIGN and you
can get a STORAGE_ERROR very soon. The solution to this problem is then to
collect the lost memory, organizing it in a free list. This can be easily done
in changing the mode of the parameter DESTINATION of the procedure ASSIGN to
"in out". This generic procedure becomes now:

     with procedure ASSIGN (DESTINATION: in out ITEM_TYPE;
                            SOURCE     : in ITEM_TYPE);

which is the implementation we currently offer.
     Every thing seems to be OK. We had just to program a free list because
our implementation does not provide garbage collection.

Now comes the problem with simple types. Example :

     subtype MY_RANGE is range MIN .. MAX ;

     MY_QUEUE is new QUEUE_G (ITEM_TYPE => MY_RANGE ; ...);

A sequence such as:

     declare
       P: LINK := new CELL;
     begin
       ASSIGN(P.DATA, ITEM);
     end;

     may raise CONSTRAINT_ERROR since P.DATA, which is of type MY_RANGE, is
checked for range conformance at entry of the procedure ASSIGN. Our compiler
checks that the value of the variable given as destination to the procedure
ASSIGN has a value in the subrange.

      Three solutions seem to remain:

     1) Furnish two packages for every data type: one for simple types and one
for complex data types: this is sad and even does not work for a  data type of
mixed kinds.

     2) Implement no free list but this is impossible in some applications
because it will soon raise STORAGE_ERROR .

     3) Put an additional generic procedure

       INIT_ITEM (DESTINATION: out ITEM_TYPE; SOURCE: in ITEM_TYPE)

to the packages which will then allow the implementor for the first assignement
for every created variable before using it. In this case there is no allocated
memory to collect and the parameter can be of mode "out". The subsequent
assignments will be done with the procedure ASSIGN and the mode "in out" will
cause no problem, because the object already contains a "reasonable" value.
This procedure would contain only a "null" statement for unconstrained types.


     Does anybody have a better idea than the number 3 above?

     More details on the packages have appeared in the proceedings of the Ada-
Europe International Conference Edinburgh 6-8 May 1986.



                         N. Ebel, C. Genillard, F. Mercier, N.H. Lam
                         Swiss Federal Institute of Technology
                         1015 Lausanne

UKC340@UKCC.BITNET (09/23/86)

HELO UKCC.BITNET
VERB ON
TICK 0001
MAIL FROM:<UKC340@UKCC.BITNET>
RCPT TO:<ARPAINFO-ADA@ARPAUSC-ECLB.ARPA>
DATA
Date:      22 Sep 86 16:30 EST
From:      UKC340@UKCC.BITNET
To:        ARPAINFO-ADA@ARPAUSC_ECLB.ARPA
Subject:   Task question

I have a question about the following ADA program:

with text_io; use text_io;
procedure tasks is

task horizontal;

task vertical;

task body vertical is
begin
    loop
        put_line("vertical");
    end loop;
end vertical;

task body horizontal is
begin
    loop
        put_line("horizontal");
    end loop;
end horizontal;

begin
    null;
end tasks;

according to the ADA reference it states that a task is to run on its
own logical cpu which to me means that the output from the above program
would be something like a few lines of "horizontal" followed by a few
lines of "vertical" followed by a few lines of "horizontal", etc.
instead all i get is "horizontal" printed over and over again.  Am
i misinterpreting what the reference is saying?  does anyone
actually get the output to alternate between vertical and horizontal?

EBEL@CLSEPF51.BITNET (11/08/86)

In the following Ada program we get an error from our Compiler. It is indeed a
strange constuction, which must be complicated to compile, but it seems to us
a correct Ada Construct. Did we miss something ?              N.,Ebel

---- cut here ---------------------------------------------------------------
with TEXT_IO;
with INTEGER_TEXT_IO;

procedure TEST is

  type COMPLEX is
    record
      RE,IM: INTEGER;
    end record;

  V: COMPLEX := (1,2);
  W: COMPLEX := (1,2);

  function "*" (V1,V2:COMPLEX ) return INTEGER is

    JUNC :COMPLEX;
    subtype ST10_TYPE is STRING(1..10);

    function "+" (V1,V2:COMPLEX) return INTEGER renames "*";

    procedure WRITE_ST10(ST10: "*".ST10_TYPE) is
    --                          |
    --                          +------+
    --                                 |
    -- Here we have an error message --+
    --
    begin
      TEXT_IO.PUT(ST10);
      TEXT_IO.NEW_LINE;
    end WRITE_ST10;

  begin
    WRITE_ST10("1234567890");
    if V1 = V2 then
      JUNC.RE := V1.RE - 1;
      JUNC.IM := V1.IM - 1;
      return JUNC+V2;
    else
      return V1.RE*V2.RE*V1.IM*V2.IM;
    end if ;
  end "*";
begin
  INTEGER_TEXT_IO.PUT(V*W);
end TEST;