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