From: ian@syacus.acus.oz.au (Ian Joyner)
Subject: Re: C++ Critique in comp.lang.c++
Organization: ACUS Australian Centre for Unisys Software, Sydney
Date: Thu, 16 Apr 1992 05:37:50 GMT

Mark,

My apologies for taking so long to respond, but I have been inundated with
mails asking for the Postscript, and many being complementary. Let me
answer some of your points.

msm@src.dec.com (Mark S. Manasse) writes:

>Ian's article on C++ is quite intersting.  It's a little too pure in its
>faith in object-orientation for my tastes, but a lot of its critiques are
>sensible.

Let me counter the notion that I am a purist. I am a practitioner, who
happens to see that where things are not implemented cleanly in the
tools we use, that this often makes life difficult. I believe we should
start with a pure base, and evolve from there, adding what is only
necessary.

>There are several points of Modula-3 where I suspect that Ian would find 
>too much similarity with C++ for his taste, and a few other places he might
>be dissatisfied.  Here's my attempt to answer his objections in advance.  
>For all those points in Ian's message I don't mention, I think that M3
>already solves the problem.

You may be jumping the gun a bit. I have not been able to pick up a book
on M3 yet, and have not programmed at all in Modula, but have in Pascal
and Object Pascal (and Simula). Many of the points in the critique are
subtle, and are often fixed in other languages in subtle ways.

>VALUE mode parameters
>----- ---- ----------

>Both C++ and Modula-3 strive to be good systems programming languages, as
>well as good object-oriented programming languages.  Consequently, there
>are features exposed by these languages that Ian doesn't like, such as
>VALUE parameter mode.  I think that both for compatability with external
>libraries and operating systems, and for efficiency, VALUE mode is
>essential.  I could believe that a persuasive argument could be made that
>READONLY should be the default.

I do not believe that systems programming and OOP are at odds.  In fact
I think they are very well suited.  But I do think the way it is done in
C++ is wrong.  Systems level programming does not require that all
structuring and good programming practice needs to be undermined.  If
so, then we should not be developing for that processor, as it must be a
very ill-defined architecture. 

It is also wrong to think that systems programming means a C style
language (or worse assembler).  If Modula-3 is a systems programming
language then it disproves this.  Burroughs has been in the business of
writing systems in higher level languages exclusively since the early
1960s, first with Algol, and then with SDL on the B1000.  This proves
that the concept of minimal extensions to languages can easily support
systems programming.  But that is now the old style way of doing it. 

Now the way that OOP implements systems programming is to embed the
system level stuff in an object of its own, and the program only
accesses the system through this clean interface.  In fact portability
is then guaranteed, as all you need to do is port the system class. 
This is not really so different to the C way of modularisation and
importing interfaces by #include, but it is much cleaner and more
sophisticated. 

I think you may misunderstand my comments on value mode parameters (if
I am not misunderstanding your comments). I am saying that value mode is
the only mode necessary in OOP. Call by reference and by name are
unnecessary, and error-prone, and I like even less the way C simulates
these by passing pointers and function pointers.


><* HIDES *> considered necessary
>----------- ---------- ---------

I can't really comment on this as I don't know about the M3 constructs
you are talking about.  However, OVERRIDES is certainly preferable to
C++'s scheme, so I think M3 is probably way ahead here.  My point though
is that where you have an issue of programmer convenience vs safety,
safety must override convenience.  Since when has programming been
convenient anyway.  I would find it much more convenient, if they just
posted out my pay cheque every week, without me having to come in and
program for it! Programmer convenience in the C sense is often only a
short term consideration.  Nothing is more inconvenient than tracking
down some very subtle errors caused by such convenience. 


>On ABSTRACT types
>-- -------- -----

>In M3, because of partial revelation, it is very easy to introduce types
>without values for some of the methods....

I'm not really sure what you mean by partial revelation in M3. Sounds
rather Biblical though :-)


>Default parameters
>------- ----------

>Ian expressed in no uncertain terms his disdain for default parameters.  I
>think that M3's default paramters are somewhat better than C++'s, and that,
>in any case, default parameters are too useful in the software engineering
>process to toss out.

>M3 default parameters are better, because M3 allows parameters to a call to be
>named.  Thus, unlike C++, I can make a procedure call where all but the last
>parameter is defaulted, by naming that parameter in the call.

Well I did say that there were other ways to provide this other than the
C++ way. Perhaps M3 achieves this. My point is to at least get these
points considered, and not just to accept default parameters as a good
thing. I do agree that the problem without them is increased name
space. But then again, I see this as a matter of programmer convenience
vs safety.


>Objects as monitors
>------- -- --------

>Ian suggests that objects can be treated as monitors, and that this paradigm
>by itself makes objects wonderful for concurrent programming.

>I'd like to support this, but it's really only the beginning of what you need
>to do.

Yes, I agree, but I wasn't going to write a book on this. I think there are
still many problems for the researchers to solve, and that is why we don't
have this with us now. But I think also that what the research is showing
is that the objects must be very clean to achieve this. C++ objects are
not clean enough.


>capitalizationShouldBeSignificant
>---------------------------------

Let me retitle this:

capitalisation_should_not_be_significant

>This is basically an unimportant surface feature of a language.  At SRC, we've
>found that using capitalization conventions to distinguish types, constants,
>and procedures from variables, fields, and methods is helpful.  And it avoids
>the awkwardness of having to come up with good names for both a type and a
>member of the type.  While you can avoid this by suffix conventions (types
>are always plural, say), it's easier to admit that Pie = (Blueberry, Cherry)
>is a nice name for the type, and that pie := Pie.Cherry is a sensible way to
>name a variable.

>But no one will ever be convinced who doesn't already believe.

I agree that this is an unimportant surface feature, but as I showed, it
can lead to really obscure errors.  The thing is the less likely that
something is going to cause an error, the more obscure the error when it
does happen.  Thus, I err again in terms of safety, rather than
programmer convenience, not that this is really at all inconvenient. 

>x.incr()
>--------

>Ian argues that 0-ary procedures shouldn't need parentheses, just as variables
>don't.  Well, maybe, but procedure calls don't have L-values.  That is, it's
>an abuse of mathematical thinking to think of variables as 0-ary functions.

No, I think the abuse to mathematical thinking is the assignment statement.
When you use a variable in an expression, it is equivalent to the notion
of mathematical function. It returns a value of a given type. Thinking of
variables and value returning procedures as both being mathematical
functions is very elegant. Besides in OOP, you should not be assigning to
the a variable entity of an object from outside the class anyway. So to
the interface user of the class, whether the entity is a variable or a
function should be indistinguishable.

>I suppose that I could be persuaded that () should be allowed after a variable
>or field name to convert it to its value.  That is, if x has a field foo,
>x.foo() is a non-designator whose value is that of x.foo.

Well, if you can be persuaded this way, then that proves that the () syntax
is superfluous, and it may as well not be there ;-)

>Call us troglodytes, call us retrograde, call us insensitive to the higher
>truth that everything is a method call. 

OK, you troglodytes, you retrogrades, you insensitive....
Well I didn't really mean that but since you asked for it, only
trying to be obliging :-)

>Some final issues
>---- ----- ------

>Ian may find a few more things about M3 that he'll hate.  I hope not, but
>who knows.  Here are a few candidates.

>1. Wrong number of friends

>In M3, given partial revelations, the notion of friends doesn't make too much
>sense. 

Ah, now I think I see what you mean by partial revelation. I suspect that
this is the very reason, why I said friends were not a very general
mechanism. Partial revelation would be exactly the mechanism I had in
mind as much better and controllable than friend. Is that right?


>2. Nested scopes, including nested procedures

>Hey, we think they're useful every now and then.  Limited scopes for
>variables can be very useful; often you can avoid introducing a
>variable until you also know how to initialize it.

Well I have spent a lot of time writing in languages that provided this,
(ALGOL, Pascal), and thinking how much better off we were than C. But
in the face of OO, and the new style of scoping that brings, I am
not so sure.


>3. Objects as references only

...

>Finally, I would list multiple inheritance, but since Ian never mentioned it,
>I'll omit it too.

No, I have no problems with multiple inheritance. But it must be used
correctly. This would have to be an instance where I would trust
the programmer to play with razor blades, and not ban them, just
because a baby might get hold of them.

Thanks for the comments, I hope that clarified a few things.
-- 
Ian Joyner                                     ACSNet: ian@syacus.acus.oz
ACUS (Australian Centre for Unisys Software)   Internet: ian@syacus.acus.oz.au
115-117 Wicks Rd, North Ryde, N.S.W, Australia 2113.
Tel 61-2-390 1328      Fax 61-2-390 1391       UUCP: ...uunet!munnari!syacus.oz
Newsgroups: comp.lang.modula3