[net.lang] Modula-2 faults

nathan@orstcs.UUCP (09/21/83)

#N:orstcs:22400002:000:3537
orstcs!nathan    Sep 18 02:23:00 1983

Concerns about Modula-2:

 There is a standard set of gripes about M-2 which I will not discuss
 here: string/character constant handling, statement delimiters, etc.
 There are also some real inadequacies which may limit
 the language's usefulness.  I believe that it is not too late to
 fix these problems.

(in advance:)
 (I don't want to get into the debate raging in net.lang.c over whether
 an i/o module is part of the language.  I claim that standard modules
 ARE, whether they have to be imported or not, because most programs'
 portability depends upon them being identical from impl. to impl.)

 Problem 1:
 The standard modules specified by N. Wirth (in his book, Programming
 in Modula-2) signal error conditions by exporting an 'error variable'.
 This makes the modules non-reentrant -- which is a real problem in a 
 language which contains multi-tasking primitives.  
 
 The solution is found in Volition Systems' own standard modules which they
 supply as alternates to Wirth's.  First, calls should RETURN an error code;
 second, a SetHandler call should be available for each module to allow 
 attempts to recover from or clean up after errors.  The handler could, at
 least, set an error flag that is available only in the scope of the calling
 routine so that other pre-empting processes would not be able to clobber it.

 Problem 2:
 Dependencies of one module on others are not explicit; these dependencies
 must be documented informally.  Judging from Volition Systems' (hereafter
 called "VS") valiant attempts, this is inadequate.  It's hard enough to
 keep documentation up-to-date when only the module's function needs 
 to be documented.

 Problem 3:
 The interrupt priority scheme for modules is just not adequate.  Apparently
 the current definition is acceptable on PDP-11's; if there is a well-
 structured method which is sufficiently general to support most 
 architectures, it should be adopted instead. (Have we any suggestions?)
 At the least, there should be some way change the priority of a module
 at run-time.  Language syntax will have to be adjusted to accommodate
 the facility, unfortunately.

 Problem 4:
 Wirth supplies a standard module Processes, with primitives for multi-tasking.
 Unfortunately, It requires that the calling function allocate stack space 
 for any new task created.  This limits its usefulness, as the programmer
 should not have to deal with such details.  On many architectures this 
 allocation can be handled much better in hardware.  A facility should
 be provided to use this hardware assist if such is available; 
 a handler would be specified which either operates on memory-mapping
 hardware or allocates stack out of the heap as it does now.

 Problem 5:
 The programmer does not have enough control over variable sizes.  
 There is no standard way to specify a 16-bit or 32-bit quantity, or
 even to tell what the compiler's WORD size is, at compile time.  On 
 16-bit machines there is apparently no way to specify a 32-bit value
 at all.  Various implementations will add support as 
 non-standard modules; these will of course *not* be portable, and 
 (in VS' case) will not even use generic arithmetic operators.

 This is not at all an exhaustive list; it represents what I was able to 
 recall at 1 am Sunday.  I hope to see:

	a: suggestions to solve these problems in an aesthetic way
	b: descriptions of other problems of equal or greater magnitude.


		Nathan C. Myers
		uucp: ...!hplabs!hp-pcd!orstcs!nathan
		Oregon State University, Corvallis

dgary@ecsvax.UUCP (09/23/83)

   My first impressions of Modula-2 were very positive, but I quickly
became disillusioned (a similar thing happened with Gerald Ford).
Since my objections are the same as everybody else's, I won't bore you
by ranting on END versus FI and OD, no character handling, cumbersome
I/O, etc.  I would like to drag two philosophical issues into the fray.
These aren't strictly specific to Modula-2, but it makes a nice
background.
   One important question is just how inflexible the language should
be in its data typing.  I'm not talking about languages like LISP and
APL which keep track of variable type for the user.  I'm speaking
rather of the FORTH-Pascal axis, with Pascal (the Edwin Newman of
programming languages) determined not to let the programmer get away
with anything, and FORTH, which would overwrite its own family if you
told it to.  Being a fan of Aristotle (I get everything he writes as
soon as it hits the stands), I prefer the middle course I get from
the PL/I compiler I use:  If I do something dangerous it raises all
kinds of hell but lets me do it.  I prefer this to being prohibited
altogether from using "dangerous" constructs, or having to fill out
twelve forms to seek permission from the compiler.  Curious that no
language definition I'm aware of (maybe Ada's, since I haven't got
through that DoD prose yet) makes provision for specifying warnings.
   Another consideration is how portable a language should be.  It
seems to me that the 8-16-32-64 family is well-enough established
(IBM and Burroughs mainframes, most minis, almost all micros) that
portability among this crowd is fine, even if we have to give up
compatibility with 12, 30, 36 and other weird architectures.  I'd
be satisfied with a language that demanded 8 bits in a character,
for example.  If only the order of bytes in a word had some official
or de facto standard...
   Anyway, what do you think?  Should languages guide programmers or
straitjacket them?  Should languages sacrifice universality if that
could make for greater efficiency and perhaps even more compatibility
among a large family of machines?

wilner@pegasus.UUCP (09/29/83)

   I must smile when ecsvax!dgary says "...the 8-16-32-64 family is
[well-established] (IBM and Burroughs...".  The famous B5000 was a
48-bit machine, the B3500 was decimal, and the B1700 was bit-addressed
(although it had 24-bit data paths).  It may seem that computer
architecture is stabilizing but I hope that's just a bad illusion.
   As to philosophy of languages, I like to recall the early days
of railroading, when each State of the Union had its own gauge for
track.  There was a portability problem at many state lines: if you
couldn't carry it from one train to the next, you were out of luck.
As I apply that lesson to languages, I conclude that each language
should mandate byte-size, byte-order, word-size and say what happens
to each bit in each operand for each operator.  That means we would
have Modula-8, Modula-16, Modula-32, etc., but the porting problems
would occur between Modula-8 and Modula-16 (say), not between Modula-16
on IBM and Modula-16 on Burroughs.  I think the problems "dgary" raises
result from languages being too loose in their semantic definitions,
then trying to protect programmers by being too restrictive in their use.

CSvax:Pucc-H:Physics:hal@pur-ee.UUCP (09/30/83)

A few comments on some of the problems presented by Nathan Myers.
Note: I use the term Modula to mean Modula-2.

Problem 1:
 Predefined Proccesses module.

Reply:
One of the nice things about Modula (and C) is that you are not forced
to use the standard modules; you can "roll-your-own".

I'm fond of saying that "Modula provides 90% of Ada's function with
10% of the complexity".  One of the features Ada provides which is
lacking in Modula is exception handling.  Nathan's mention of SetHandler
points out that this can be provided in Modula without making it part of
the language.  I'm more encouraged.
=================================================================
Problem 2:
 Module dependencies not being explicit.

Reply:
By module dependencies not being explicit, I assume that what is meant is
that if module A imports from module B which imports from module C, then
module A's dependence on module C is not apparent from the text of module
A.  But note that this dependence is still available to the compiler since
when A is compiled and references B, the definition module for B must be
scanned by the compiler and hence dependence on C is visible.

A related problem that is giving me problems (since I'm writing a compiler)
is illustrated with the following example.  Assume modules A, B, and C
have the dependencies mentioned in the previous paragraph.

DEFINITON MODULE C;
EXPORT QUALIFIED Type1;

TYPE Type1 = (con1, con2, ...); (* or a record type *)

END C.

DEFINITION MODULE B;
FROM C IMPORT Type1;
EXPORT QUALIFIED Btype;

TYPE Btype = RECORD
		f1: Type1;
	     END;
END B.

Now let's concentrate on what identifiers are known in module A which
imports type Btype from B.  The language definition states that when
a record type is exported then the field identifiers are also exported.
But what about the types of those fields!?  Must Type1 be placed on the
export list of module B?  This problem is the same whether or not Type1
is imported in to B or defined in B, as long is Type1 is omitted from
the export list.  What's to be done?
======================================================
Problem 3:
 Interrupt priority scheme not adequate.

Reply:
Changing the priority of a module at runtime could be done with some
appropriately named routine imported from SYSTEM.  In any case no
changes to the language syntax are required if the module priority
is simply regarded as the module's initial priority.
======================================================
Problem 4:
 Standard module Processes.

Reply:
I think the "roll-your-own" method (writing your own Processes module)
solves this adequately.  In this case Modula-2 retreated a little from
"Modula" by removing the Processes primitives from the language.
This gives you the freedom to use your own schedluling algorithm.
=======================================================
Problem 5:
 Programmer control over variable sizes.  

Reply:
Can't "roll-your-own" here.  If Modula had operator overloading, as in
Ada, you could extend the numeric types without altering the language.
For my own compiler (MC68000), I side-stepped this one by making the WORD
size 32 bits.
==============================================

My reference is the "Report" as it appears in the book:
"Programming in Modula-2" by (you know who)
(New York: Springer-Verlag) 1982.

Have there been changes in language?  Do I need to go out and buy a new book?
Seems to me I heard something about "corrections" someplace.

				Hal Chambers
				Physics Dept.
				Purdue Univ.
				(...!pur-ee!pur-phy!hal)

patcl@tekecs.UUCP (10/10/83)

Subject: Re: Re: Modula-2 faults
--------

Export of record types whose field types are imported
does not really create any conceptual problem. It is no
problem for the compiler, since all relevant symbol table
information should be available in the definition module
which exports the field type. For example, if A exports
type foo = (red,green,blue), and B exports type bar =
RECORD glorch: foo; END, then during compilation of the
definition module for B, the relevant information about foo
would have been inserted in B's symbol table, which in turn
would be available to an importer of bar.
Note that this information may only be necessary to determine
the size of bar, for code generation purposes.
The scope of foo need not be the same as the scope of bar,
if foo is not exported and imported to all modules that bar is;
the field glorch may still be used, for example, as an argument to an
imported procedure, without having direct access to its type.

Pat Clancy
Tektronix

thomas@utah-gr.UUCP (Spencer W. Thomas) (10/17/83)

Why is this discussion of Modula going on in net.lang instead
of net.lang.mod2?

=Spencer