[comp.lang.modula2] C++ vs. Modula-2

frode@m2cs.naggum.se (Frode Odegard) (01/17/89)

This posting is a reaction to some of the statements made in the on-going
C++ vs. Modula-2 debate here in comp.lang.modula2. The quotes are from several
postings.

****..VAR FLAME: BOOLEAN; BEGIN FLAME := TRUE; *****

>> Is C++ not appropriate for general purpose? Why?

>I see no reason why it shouldn't [be]. C++ basically contrains everything that
>Modula does, and MUCH more.

C++ has a notion of scoping that makes me s**k. Modula-2 has better scoping.
The beauty of a language is not found in its size. C++ is too complex.

>Its major drawback is what is inherited from C, which makes it very easy to
>write terrible code. But then, bad code can be written in ANY language.

The point is, people won't write purely o-o in C++, because they'll use lots
of exisiting C libraries which are not exactly o-o.

>C++ lacks the strict checks of module dependencies that are performed by (most)
>Modula compilers. However, in a UNIX environment (with make), the C/C++ approach
>works equally well (and is much more flexible).

Bull! First of all, I would never use a programming language (for a project over
1000 lines) which doesn't support separate compilation of module/class definitions
and implementations. Second, how can the use of a static Makefile give you more
flexibility???  At least Modula make's will find out the module dependencies
by checking .sym and .o files. What's the point of using an o-o language (which
C++ claims to be) if you have to update Makefiles every time class dependencies
change??? Bah! So much for the Smalltalk inheritence, right? :-)

>> What are the deficiencies of Modula-2 as a system programming language?

>In my eyes, the lack of conditional compilation. Look at C code that is portable
>across widely differing hardware and operating systems. GNU emacs, for example,
>comes in one distribution for all supported systems. To configure it for a
>particular hardware/operating system, oone only changes a few lines (usually
>1 to 3) in the configuration file and types "make". I don't see how that could
>reasonably be done in Modula.

Have you actually _programmed_ in Modula? Preprocessors and other utilties are
not magically built into a computer language (except maybe Lisp and Smalltalk,
where there's no border between language and environment). Make can be used
for Modula-2, too. I don't use it because I have better tools than the make
that comes with SunOS. I could have used cpp on Modula-2 code, but because I
wish to keep my source code clean of non-standard syntax, I don't. There is
a Modula-2 preprocessor available for very little money which has all the cpp
facilities but demands that commands for it are placed in comment brackets
to avoid the introduction of non-standard syntax. Why should I use old UNIX
tools when I have better tools which make use of Modula-specific facilities?

>Second are address computations. Their definition in Modula is WRONG! If you
>add one to a pointer in Modula, that's one storage unit (you don't even
>know whether it's one byte or one word). in C/C++, adding one to a pointer
>to char increments the address by one byte, incrementing a pointer to int
>increments the address by sizeof(int). That's the way it should be.

Just like ++ and -- are in C mainly because of the PDP-11 instruction set :-),
Modula-2 has traditionally had the type WORD in SYSTEM. As Modula-2 was ported
to micros, compiler writers added SYSTEM.BYTE. There was some confusion about
ARRAY OF SYSTEM.WORD vs. ARRAY OF SYSTEM.BYTE, and to resolve this, ISO Modula-2
will have something called SYSTEM.SAU. SAU stands for Smallest Addressable Unit,
and thus the old BYTE <-> WORD confusion has been removed. Compiler implementors
are also required to define BYTE and WORD in terms of SAU in SYSTEM. The type
ADDRESS is defined as POINTER TO SAU.

The reason why Modula doesn't have +,-,DIV,REM,* defined for ADDRESS values is
that it is considered machine-specific. There are lots of weird machines out
there, you know. Compiler implementors are free to put as much low-level,
machine-specific features in SYSTEM as they want.

Modula-2 hackers know that modules which import from SYSTEM are machine/os/
compiler-specific anyway.

>Allocation of space for records (particularily alignment) is unclear in Modula.
>Operating system calls frequently return pointers to records with some operating
>system-defined layout. Mapping these on Modula records is, due to alignment,
>compiler dependent.

It's not a big problem, really. When you do Modula-2 interfaces to OS calls,
you're operating on a low level of abstraction anyway. The data structures will
not be portable to another OS. They will however, with some usage of subrange
types (another good Modula-2 feature which C/C++ don't have) be portable from
compiler A to compiler B. We've written a very complete interface to the SunOS
system calls, and it was not difficult at all.


>>What I particulary want to know is:
>>  Which of the two languages, Modula-2 and C++, is better suited for
>>  numerical computation?

>Both have serious deficiences here. The most serious one is probably the
>impossibility to pass multi-dimensional arrays of vaying size to subprograms.
>Linearizing your matrices to be able to pass them to subprograms is a step
>back towards assembler code.

What's the problem? Since Wirth released the paper "revisions and amendments
to Modula-2" quite some time ago, multiple-dimension open arrays has been
_in_ the language. It is also in ISO Modula-2 [which is now only a few months
away]. If C++ has so many fantastic things, why doesn't it have this feature
(BTW, I thought it _had_, honestly)?  Wirth consentrates on the essential
features when designing languages, that's why his languages are rather small
and clean.

> <goes on and on about library issues>
The library issue is being fixed once and for all in the upcoming ISO standard.
This hasn't been a huge problem for big Modula-2 projects (at least that's my
experience) because "real Modula hackers write their own libraries anyway".
Standard libraries: great for text-books and classes, but some of the big
Modula projects have done everything from the compiler up to the 3,000,000-line
application in-house. What's a 3,000-line library, then? A couple of weeks of
hacking? C's standard library is rather UNIX-oriented. The 4-5 library styles
used in different Modula implementations also lean towards different operating
systems (Medos for example).

>Personally, I despise all procedureal languages for being such. They are
>semantically obfuscative, period.
Not true. ISO Modula-2 is defined in VDM. It works!

>Call me a heretic, but I often think that the safety-madness of Modula-2 is the
>result of completely loosing sight of the purpose of programming: to get things
>done.

Heretic! :-)  I quite disagree. The safety of Modula-2 (Modula-3 goes even further I
believe) has saved a lot of money for its users. Modula-2 users spent much less
time that C users digging on a low level trying to find a bug that wasn't seen
by the compiler.

Working on programming environment research, I believe that the trend of the future
is towards more intelligent environments. I don't believe in the C culture that says
"leave my hacks alone, I only run lint on Christmas Eve".

C++ is not as good as Modula-2 for large projects, I expect, because it doesn't
support separation (by compilation, by rule, defined in the language etc.) of class
definitions and implementations.

>In the Modula-2 context, I am sure that the machine-specific vector extensions
>to the CDC Pascal/Modula-2 compiler (for the Cyber 205 & ETA-10) are not
>syntactically valid on other machines.

If someone does non-standard Modula-2 implementations, I don't think Modula-2
can be blamed. Compiler/machine-specific extensions to the language should be
put in SYSTEM.

>Including .h files is not the same as importing modules, no matter what a C
>hacker tells you.

Right!! :-)  This cannot be repeated too often. One must tell people that
.h files are textually included and expand to "extern func_name;" declarations,
which the same old ASM/FORTRAN story. C hasn't got a module concept.

>Conditional compilation is not the same as dead code elimination.

I agree. However, I'm not sure preprocessors repesent a good solution to
portability. I think Modula-2's module concept is vastly under-estimated
when it comes to writing portable Modula-2 software. I certainly dislike
solving the problem by introducing language extensions. I work for a company
which is building a Smalltalk/Interlisp-D inspired programming environment
for large-scale Modula-2 projects (runs on Suns and VAXen). I think we have
solved a lot of problems by creating better Modula-2 tools instead of extending
the language.

*** FLAME := NOT FLAME; END ******

 					- Frode
-- 
| Frode L. Odegard         |"The world is coming to an end! Repent and|
| Modula-2 CASE Systems    |rm /bin/cc"                               |
| NORWAY (EUROPE)     	   |                                          |
| Email: frode@m2cs.uu.no  |                                          |

heiser@iis.UUCP (Gernot Heiser) (01/22/89)

In article <122@m2cs.naggum.se> frode@m2cs.naggum.se (Frode Odegard) writes:
>The point is, people won't write purely o-o in C++, because they'll use lots
>of exisiting C libraries which are not exactly o-o.

Granted. But people aren't going to program purely OO in Modula since the
language doesn't support it at all. So, what's your point?

>>C++ lacks the strict checks of module dependencies that are performed by (most)
>>Modula compilers. However, in a UNIX environment (with make), the C/C++ approach
>>works equally well (and is much more flexible).
>
>Bull! First of all, I would never use a programming language (for a project over
>1000 lines) which doesn't support separate compilation of module/class definitions
>and implementations.

May I return that compliment? Look at the language BEFORE flaming! Fact is that
 - nowhere in the (current) definition of Modula-2 it is said that DEFINITION
MODULES are compiled. In fact, there are compilers (e.g. the Powell compiler
from DEC) that don't.
 - The important point is that usage of an external entity is always checked
against its definition. This is the case with C++.
 - The strict checks using module keys as done by most Modula-2 systems is
relatively save but also creates lot of overhead so that in the long run it
often costs more than it buys. In a large system you cannot afford adding
comments to a central DEFINITION MODULE because you would have to recompile
everything. Also one would like to be able to make upward compatible changes to
modules (e.g. adding procedures) without recompiling the whole system.

Incidentally, this last point was solved much better by a SIMULA-67 compiler I
used a lot almost 10 years ago. SIMULA does not have the notion of separate
definition and implementation but the compiler would still produce a symbol
file when compiling an external class. It was smart enough only to produce a
new symbol file if anything really changed. Of course, this scheme could be
easily incorporated into Modula, but this seems to be against the "small is
beautiful" spirit.

>What's the point of using an o-o language (which
>C++ claims to be) if you have to update Makefiles every time class dependencies
>change??? Bah! So much for the Smalltalk inheritence, right? :-)

Is that your idea of OO programming? Frequently changing class dependencies? :-{

>>> What are the deficiencies of Modula-2 as a system programming language?
>>In my eyes, the lack of conditional compilation. [ ... ]
>Have you actually _programmed_ in Modula? Preprocessors and other utilties are
>not magically built into a computer language (except maybe Lisp and Smalltalk,
>where there's no border between language and environment).

Yes, I have programmed in Modula, quite a bit acually. But have you ever
written a large code that was to run on _many_ different architectures/operating
sytems? And have you ever programmed in C++? We are not discussing how each
language could be mocked up o make it more usable, rather how usable it is in
its current state. And fact is, that cpp _is_ an integral part of the C/C++
languages, while this is _not_ the case with Modula. And fact is that you _can_
write portable code in C/C++ while this is virtually impossible with current
(pre ISO) Modula-2. (I hope it will be possible in ISO Modula.)

>>Second are address computations. Their definition in Modula is WRONG! If you
>>add one to a pointer in Modula, that's one storage unit (you don't even
>>know whether it's one byte or one word). in C/C++, adding one to a pointer
>>to char increments the address by one byte, incrementing a pointer to int
>>increments the address by sizeof(int). That's the way it should be.
>
>Just like ++ and -- are in C mainly because of the PDP-11 instruction set :-),

and INC/DEC in Modula because of the Lilith instruction set...

>The reason why Modula doesn't have +,-,DIV,REM,* defined for ADDRESS values is
>that it is considered machine-specific.

wrong again. These _are_ defined for ADDRESS values (check PIM2, ed.3, p 166)
but, as I said before, their definition is WRONG (i.e. such that ADRESS
computations are, unnecessarily, non-portable).

>Modula-2 hackers know that modules which import from SYSTEM are machine/os/
>compiler-specific anyway.

You see, that's the difference. Modula-2 somehow seems to convey that every
program that uses low level features is by definition non-portable. But in fact
you can go a long way doing low-level stuff portably if things are done right.
The way address computations are defined in C _does_ allow portable use.

>>Allocation of space for records (particularily alignment) is unclear in Modula.
>>Operating system calls frequently return pointers to records with some operating
>>system-defined layout. Mapping these on Modula records is, due to alignment,
>>compiler dependent.
>
>It's not a big problem, really. When you do Modula-2 interfaces to OS calls,
>you're operating on a low level of abstraction anyway. The data structures will
>not be portable to another OS. They will however, with some usage of subrange
>types (another good Modula-2 feature which C/C++ don't have) be portable from
>compiler A to compiler B. We've written a very complete interface to the SunOS
>system calls, and it was not difficult at all.

Note that I said "compiler dependent", not OS dependent. Of course such stuff
is OS specific. However, your Modula-2 SUN-OS interface will be heavily
compiler dependent (I am speaking from experience). Particularly subranges are
very much subject to the compiler writer's taste. Some allocate the same space
as for INTEGERs, others don't.

That's exactly the kind of problems you do not have in C/C++ (or only to a much
lesser degree).

>What's the problem? Since Wirth released the paper "revisions and amendments
>to Modula-2" quite some time ago, multiple-dimension open arrays has been
>_in_ the language.

Sorry, but it just aint so. The "revisions and amendments to Modula-2" were
published prior to the 3rd ed. of PIM2 and neither the former nor the latter
contains multiple-dimension open arrays. Apparently some of Wirth's latest
compiler do contain it, but at this time it can hardly be considered a standard
feature. If it is going to be in the ISO standard, that's only for the better.

>The library issue is being fixed once and for all in the upcoming ISO standard.
>This hasn't been a huge problem for big Modula-2 projects (at least that's my
>experience) because "real Modula hackers write their own libraries anyway".

This also seems to be a widespread philosophy among Modula users: There are so
many wheels to be re-invented, aren't there?

>Standard libraries: great for text-books and classes, but some of the big
>Modula projects have done everything from the compiler up to the 3,000,000-line
>application in-house. What's a 3,000-line library, then? A couple of weeks of
>hacking?

Wrong again. A library that must support portable software needs _much_ more
care in design than other code, unless you are willing to redesign it whenever
you are targeting it at another host system (at the expense of modifying all
the code that depends on it). And, of course some parts (or most of it,
depending on how it's written) of the library need to be re-implemeted for each
port. A "few weeks hacking" will only increase your problems in the long run.

>Modula-2 users spent much less
>time that C users digging on a low level trying to find a bug that wasn't seen
>by the compiler.

... and, according to my experience, much more time in patching around compiler
bugs. But that's of course not a problem with the language per se. I do agree
that Modula is a much nicer, cleaner language, put particularily for large
projects I would prefer C++ anytime.

>I don't believe in the C culture that says"leave my hacks alone, I only run
>lint on Christmas Eve".

There is no more linting with C++, the compiler does its job properly.

>C++ is not as good as Modula-2 for large projects, I expect, because it doesn't
>support separation (by compilation, by rule, defined in the language etc.) of class
>definitions and implementations.

C++ is far superior to Modula-2 for large projects because it supports _real_
data abstraction, real OO programming (with inheritance not only of attributes
but also of methods) and many other small things like in-line procedures,
constant array parameters (without the overhead for copying) and and and...

>>In the Modula-2 context, I am sure that the machine-specific vector extensions
>>to the CDC Pascal/Modula-2 compiler (for the Cyber 205 & ETA-10) are not
>>syntactically valid on other machines.
>
>If someone does non-standard Modula-2 implementations, I don't think Modula-2
>can be blamed. Compiler/machine-specific extensions to the language should be
>put in SYSTEM.

You didn't get the point that person was making. The point is if your standard
language is not powerful enough to make use of essential hardware facilities
(in this case vector hardware) than you may be FORCED to use non-standard
features. But you still want to keep your programs portable which requires
conditional compilation.

>C hasn't got a module concept.

But C++ has and we were talking about Modula-2/C++/FORTRAN

>I agree. However, I'm not sure preprocessors repesent a good solution to
>portability.

I think it's essential.

>*** FLAME := NOT FLAME; END ******

I hope I remained factual.

>| Frode L. Odegard         |"The world is coming to an end! Repent and|
>| Modula-2 CASE Systems    |rm /bin/cc"                               |
>| NORWAY (EUROPE)     	   |                                          |
>| Email: frode@m2cs.uu.no  |                                          |


-- 
Gernot Heiser                   Phone:       +41 1/256 23 48
Integrated Systems Laboratory   CSNET/ARPA:  heiser%iis.ethz.ch@relay.cs.net
ETH Zuerich                     UUCP (new):  heiser@iis.uucp
CH-8092 Zuerich, Switzerland    UUCP (old):  {uunet,mcvax,...}!iis!heiser