[comp.lang.modula2] safe ADT's

Klaiber@LOUIE.UDEL.EDU.UUCP (02/09/87)

   > It is impossible to implement a "safe" ADT in Modula-2. It would
   > require some modifications of the language. You would need full
   > control over the objects of this type. The exporting module must be
   > informed on allocation and deallocation of this object (i.e. at
   > scope entry and scope exit). Furthermore you must have control over

		.... desirable enhancements yo MODULA-2 ....

   > After you have done these modifications you would have a nice language but
   > you will have to find a new name for it because it wouldn't be Modula-2
   > any longer.
 
   >         Thomas Habernoll  -  HABERNOL@DB0TUI11.BITNET


I wholeheartedly agree -- there are some downright AWFUL omissions in
MODULA-2; the inability to control creation/assignment etc. of ADTs is one
of these. I actually think it makes opaque types practically useless
(together with the limitation of 'opauqe's to pointer types). Why did Wirth
have to spoil the nice concept of modularity and information hiding in this
way?


=======================
Another thing:

 (* From: Bob Pendleton <uplherc!esunix!bpendlet@utah-gr.arpa> *)

> Could we get a discussion going on exception handling in Modula-2? The lack
> of a defined exception handling mechanism in the language is, in my opinion,
> a serious flaw in the language. Rather like a flaw in a diamond.
> 
> I've read that C's setjmp and longjmp have been implemented and used with some
> versions of Modula-2, and I've seen the description of exception handling in
> Modula-2+ described in "Extending Modula-2 to Build Large Integrated
> Systems" in the November, 1986 edition of IEEE Software. I'm interested in how
> people have done exception handling in systems they have written in Modula-2
> and what exception handling mechanisms have been implemented in other
> versions of Modula-2.

Usually, you have just the "good old" solution: After every call to a
library function, have an 'IF'-statement check for every possible error,
combined with either a RETURN to abort the current procedure or (sa to say,
I've seen this one all too often) a write-statement and a HALT.
I definitely DON't like the setjmp/longjmp solution, since -- powerful as
it is -- it can be ABused too easily. Also, the code is still kind of
awkward.
The follwing is no really well tought-out, but maybe you would like to
consider it:
with the help of procedure variables, SOME exception handling could
be done -- however, this requires a VERY disciplined programmer and the
rewriting of existing library modules:
Have a module Exceptions which exports
   TYPE ExceptionHandler = PROCEDURE (CARDINAL);
and
   PROCEDURE EnterBlock(Handle:ExceptionHandler);
   PROCEDURE ExitBlock;
   PROCEDURE Raise(ErrorId:CARDINAL);
   PROCEDURE ErrorOccured:BOOLEAN;
Now have all library modules import Exceptions and -- if an error occurs --
call Raise(...). Raise could then look for the current exception handler and
invoke it. Note that this requires the application program to supply an
exception handler explicitly (and signal when the block associated with
this handler is exited). Also, this cannot abort the block where the
exception occured, the programmer would have to do that him/herself --
again using that additional IF-statement. What in Ada could be written as

procedure Blah is
begin
   whatever(....);		-- may cause an exception
   something_else(...);		-- only if whatever() went fine
exception
   when ... => 
end Blah;


should look like this in Modula:

PROCEDURE Blah;
   PROCEDURE Cleanup(ErrorCode:CARDINAL);
   BEGIN
      ... (* handle error *)
   END Cleanup;
BEGIN (* Blah *)
   EnterBlock(Cleanup);			(* to install the handler	*)
   Whatever(...);
   IF ErrorOccured() THEN RETURN; END;	(* abort after error		*)
   SomethingElse(...);
   ExitBlock;
END Blah;


Now what do you think -- right, it's kludgy, clumsy and awful. Not that Ada
knows it all, but I can't help the feeling that -- if Ada has too many
features -- MUDULA-2 has too few...


==================
More:

Why are the concepts of 'WORD', 'SET', 'SIZE' etc. so fuzzy in MODULA-2? I
_do_ agree that you can't have low-level _and_ perfect portability, but
does one have to complicate the issue by choosing to make WORD the
"natural" wordlength of the computer and have SIZE return sizes in
"allocation-units"? To see where this leads, consider the following
machines:

(1) one compiler for the VAX:
	SIZE and ALLOCATE use bits, addressing unit is byte
(2) another compiler for an IBM-PC:
	SIZE uses WORDs, a WORD being 2 bytes, addressing unit is byte
This makes address arithmetic VERY machine-specific and error-prone:
Consider a block of memory containing some data of type T; let B be the
base ADDRESS of the block. To get the address of the (i)th element in 
the block, you have to write: (assume that T occupies multiple of 8 bits)
(1) B + i * (TSIZE(T) DIV 8)
(2) B + i * (TSIZE(T) * 2)
Moreover, try to pass some variable of type T, where T occupies an odd
number of bytes, to an ARRAY OF WORD on machine (2)... Won't work unless
either (a) one uninitialized byte at the end doesn't matter or (b) you
explicitly pass the element size in BYTEs to the procedure!!!!

Why not have a type -- say -- UNIT equal to the addressing unit of the
machine and then have SIZE, ALLOCATE etc all use sizes in units of UNIT.
This would mean in cases (1) and (2), we could write
(any)   B + i * TSIZE(T)
for our above example.

I agree that address arithmetic is not the best idea, but there are times
when it's difficult to avoid (try writing operating systems!)


======================================

The bottom line? As Thomas Habernoll said, you could enhance the language.

Well, as far as I'm concerned, I am ready for Modula-3 !!!


	Alexander Klaiber  (kliber@dewey.udel.edu)


------------
These opinions are not neccessary those of any employer, not neccessary
mine and maybe not neccessary