[comp.lang.smalltalk] C++ vs. Other OOLs

dmg@ssc-vax.UUCP (David Geary) (04/15/89)

  Although I am quite experienced in C, I have never written one line of code
in C++ (or any other ool), although I expect that to change in the near future.
  Anyway, I am very interested in object oriented programming, and C++.  
I would like to start a discussion concerning C++ and ool's.  I would 
like to see comparisons of C++ vs. other object oriented languages such as:

C++ vs. Modula2
C++ vs. Lisp
C++ vs. SmallTalk
C++ vs. Prolog
C++ vs. Objective C

  I'd like to know how C++ stacks up against the others as far as:

It's degree of "object-orientedness"
Speed and portability.

  It seems to me that C++ is not as "object-oriented" as Lisp, SmallTalk, 
and the like, but then again, realize that I don't know what I'm talking 
about ;-).  Also, it seems that C++ would be more efficient, and more 
easily portable than the "others", but, then again ...
-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ David Geary, Boeing Aerospace, Seattle                 ~ 
~ "I wish I lived where it *only* rains 364 days a year" ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

alan@rnms1.paradyne.com (Alan Lovejoy) (04/19/89)

In article <2602@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes:
>I would like to start a discussion concerning C++ and ool's.  I would 
>like to see comparisons of C++ vs. other object oriented languages such as:
>
>C++ vs. Modula2
>C++ vs. Lisp
>C++ vs. SmallTalk
>C++ vs. Prolog
>C++ vs. Objective C
>
>  I'd like to know how C++ stacks up against the others as far as:
>
>It's degree of "object-orientedness"
>Speed and portability.

-- Portability --

1) Language portability is a function of how similar the compilers for different
systems are and the breadth and depth of STANDARD functions that are provided
via STANDARD interfaces.  This is largely an extra-linguistic issue that
has more to do with the history and culture of different language communities
than it has to do with the technical merits of languages as languages.

Smalltalk is the winner here, with C++ a strong runner-up.

2) The other issue is how many different systems have implemantions of your
language available.

C++ wins hands down on this point.

-- Speed --

Speed is just as much an implementation issue (compiler AND host CPU) as it is
a function of the language (syntax, semantics).  Actually, I don't think
syntax has any effect on speed at all, unless the translation and execution
of the program are both being timed (e.g., an interpretive implementation).  
The semantics of a language affect speed of execution in several ways:

1) Whether values can be computed during language translation or only during
program execution (e.g., dynamic vs. static binding, where the "value" being
computed is the address of the object/function which is being referenced).

C++ and Modula-2 are essentially tied for first place on this one.

2) How close the expression of an algorithm and/or data structure can be 
to its mathematically optimum form.  

Bit manipulation in a language that doesn't know how to talk about bits may 
suffer a performance penalty.  The performance penalty comes from the extra 
work that must be done in order to simulate what you really wanted to do using 
something else as a model.  The extra work can involve both translations between
different representations and adjusting for the differences between the actual 
behavior of your model and the object/process being modeled.

No clear winner is evident, but C++ may have it by a nose.

3) The amount of information that can be provided to the code generator and/or
optimizer about the intended use/semantics of objects.  

Optimization depends upon knowing invariants.  If the places from which a 
variable is referenced are always computable at translation time, then the 
variable can be kept in a register.  Otherwise, it cannot, because the points 
of access to the value of the variable are not known to be invariant at 
translation time.

Modula-2 has the edge on this metric.

4) The semantic distance between the operations/data structures provided
by the source language and the target language (e.g., the machine language).

The greater the distance between the semantics of the source langauge and target
language operations, the more target language operations will be necessary in 
order to express the semantics of each source language operation.  However,
because the space in which this "semantic distance" is measured is
multidimensional, it is important to consider along what dimension(s) this
distance lies.  The semantic distance between integer addition and floating
point addition is not in the same dimension as the semantic distance between
floating point addition and floating point vector addition, which is in a 
dimension I will call primitiveness.  Floating point addition is more primitive
than floating point vector addition.  Or to state it conversely, vector
addition is "higher level" than scalar addition.

The greater the semantic distance between the primitiveness of the source
and target languages (assuming the source language is less primitive than
is the target language), the more opportunity there is for optimization of 
translations.  This is because the relative semantic granularity of the target
language with respect to the source langauge is a function of the difference
in primitiveness level.  Greater granularity permits greater flexibility
in tailoring translations so that they precisely express the semantics
of the source construct without unwanted/unnecessary side effects.  And
the fact that larger differences in primitiveness mean more target operations
for each source operation is mitigated by the fact the work performed by
the target language operations is inherent to the definition of the source
operation, because of the definition of primitiveness.  There is no such
thing as a free lunch.  

On the other hand, the implementation of unsigned 32-bit integer math on
a machine that only has signed 32-bit integer arithmetic operations would
exhibit the opposite effect.  The semantic distance may require multiple
machine operations for some or all unsigned integer operations in the source.
The unwanted side-effects of the semantics of signed integer arithmetic
have to be compensated for by means of additional target language operations.
The extra work is not inherent to the semantics of unsigned integer arithmetic.
Therefore, the extra work is a performance loss.

Prolog, Lisp, Smalltalk, Objective-C, Modula-2, C++, in that order.

Disclaimer:  my evaluation of the languages above is based on my estimation
of what could be done with ideal compilation technology.   Your mileage
may vary, etc.

 
-- Object Orientation --

I don't see object orientation as an end in itself, but rather as a tool for 
designing languages with great abstractive power.  To me, the quality of a
language is a function of its ability to EFFICIENTLY and SURELY define, express,
manipulate and implement abstractions.  However, now is not the time
to write my doctoral dissertation of programming language design.  This
posting is long enough already.

The definition of "object oriented language" is open to debate.  Instead of
debating the minimum set of attributes that an object-oriented language 
should have, it is more instructive to consider the ideal case.  

First, some definitions: A class is a set of values and the functions/relations
defined on the members of that set.  An object is an instance of a class which
represents one of the values in the set, that is, one of values of the class.

Inheritance is the ability to define a new class in terms of its differences
(extensions, deletions, changes) from some other pre-existing class.

Prolog, Lisp, Smalltalk, Objective-C, C++, Modula-2

The ideal object-oriented language would:

1) Have user-definable classes.

Smalltalk, Objective-C and C++ satisfy this requirement.  Lisp and Prolog  
permit the programmer to define his own class mechanism.  There are versions 
that come with classes built in.  Modula-2 has modules, but these differ from 
true classes because they cannot be instantiated.  A module with exports a
single opaque type almost qualifies as a class, but it's an ugly and inelegant
class at best.  Whatever it is, it does not allow class inheritance, a fatal 
flaw.

2) Have class inheritance.

Smalltalk, Objective-C and C++ satisfy this requirement. Lisp and Prolog
permit the programmer to include an inheritance mechanism in the implementation
of classes.  Modula-2 does not support inheritance at all.

3) Allow function/operator overloading.

Smalltalk, Objective-C and C++ satisfy this requirement.  Lisp and Prolog 
permit this to be constructed as part of the implementation of classes.  The 
best Modula-2 can do to emulate this is by dynamically binding procedures to 
procedure variables:  it's very, very ugly and suffers from severe limitations.

4) Be completely polymorphic.

This is actually the most important requirement for abstractive power.
Problems with abstraction mechanisms are usually caused by a lack of
polymorphism.  

Smalltalk and Lisp are highly polymorphic.  Next is Objective-C and Prolog.
Then C++, and last is Modula-2.

I considered defining polymorphism, but I don't have the time right now.
If you really want to know, post the question.  Someone will answer. 
Perhaps even me!


--
Alan Lovejoy; alan@pdn; 813-530-2211; AT&T Paradyne: 8550 Ulmerton, Largo, FL.
Disclaimer: I do not speak for AT&T Paradyne.  They do not speak for me. 
_________________________Design Flaws Travel In Herds_________________________

mthome@bbn.com (Mike Thome) (04/19/89)

In article <5947@pdn.paradyne.com> alan@rnms1.paradyne.com (Alan Lovejoy) writes:
>In article <2602@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes:
>>I would like to start a discussion concerning C++ and ool's.  I would 
>>like to see comparisons of C++ vs. other object oriented languages such as:
>>C++ vs. Lisp
>>  I'd like to know how C++ stacks up against the others as far as:
Just to add to an otherwise complete (from my personal knowledge)
synopsis of object oriented languages:  I assume that the previous
message's discussion of Lisp's "object orientedness" was based solely on
the "defstruct" construct covered in CommonLisp The Language.  It is
certainly worth mentioning that a true object-oriented Lisp system has
been accepted into the "official" CommonLisp set by the CL cleanup
committee.  I'll try covering a few of the original message's points with
regards to CLOS (CommonLisp Object System), but a more complete
discussion is available in a book by Sonya Keene entitled "Object
Oriented Programming in CommonLisp" (or somesuch - Addison Wellesly, I
believe)...

>-- Portability --
>1) Language portability is a function of how similar the compilers for different
>systems are and the breadth and depth of STANDARD functions that are provided
>via STANDARD interfaces.  This is largely an extra-linguistic issue that
>has more to do with the history and culture of different language communities
>than it has to do with the technical merits of languages as languages.
>Smalltalk is the winner here, with C++ a strong runner-up.
I'm not sure I see how this is *at all* a linguistic issue - it sounds
as thought you are talking more of programming environment and fidelity
of implementations than anything else.  Frankly, I'm surprised that C++
is listed in the same sentence as Smalltalk in this regard - Smalltalk is
an entire integrated environment implemented in itself... the only other
similar systems that come close are Lisp Machines (from various vendors)
running Flavors - perhaps some of the pascal P-machines might be grouped
in the same way.

>2) The other issue is how many different systems have implementations of your
>language available.
>C++ wins hands down on this point.
Agreed.  I would add that most machines that run commonlisp are also able
to run at least one of the CLOS implementations (I know of at least two -
PCL, which runs on just about any CL out there - certainly all the major
vendors are covered, and TI has a native version (Symbolics has announced
one as well, but it isn't expected for several months).  PCL has the
advantages that it is free (thanks to the good guys at Xerox) and easily
portable.  Native versions are faster).

>-- Speed --
>Speed is just as much an implementation issue (compiler AND host CPU) as it is
>a function of the language (syntax, semantics).  Actually, I don't think
>syntax has any effect on speed at all, unless the translation and execution
>of the program are both being timed (e.g., an interpretive implementation).  
>The semantics of a language affect speed of execution in several ways:
>...  There is no such thing as a free lunch.  
I'll not itemize responses to this section: a summary of this whole issue
is covered by that final line:  Expressive power usually requires more
machinery to support it - it is exactly the same issue as the
Lisp/Smalltalk vs. C/ModulaII camps (which we will NOT go into here -
suffice it to say it all depends on what you want to do and how you want
to do it... and possibly what sort of hardware you want to do it on).
This applies to CLOS vs. C++ just as well:  C++ can be fast because much
of the "object oriented"ness can be "compiled out" and requires little
runtime support (not to be taken as other than praise - C++ does very
well at furthering the "charter" of C).  CLOS (for instance) must be able
to deal with a far more complex (dynamic) runtime environment than C++,
as well as such things as multiple class inheritance, multiple argument
dispatch, etc.  Even so, the better CLOS implementations pay surprisingly
little cost over funcall. (BTW, some people in the object-oriented
community have object to calling CLOS "object oriented" because it is not
based on the usual message passing protocols - rather it uses the generic
function metaphor).
Some of the Lisp-running hardware is able to provide much better run-time
support for CLOS than any conventional-architecture machine will be able
to for C++ (or successors).  Both Symbolics and TI have loadable
microcode sets capable of implementing the basics as instructions.

>-- Object Orientation --
>The definition of "object oriented language" is open to debate.  Instead of
>debating the minimum set of attributes that an object-oriented language 
>should have, it is more instructive to consider the ideal case.  
>  First, some definitions: A class is a set of values and the functions/relations
>defined on the members of that set.  An object is an instance of a class which
>represents one of the values in the set, that is, one of values of the class.
>  Inheritance is the ability to define a new class in terms of its differences
>(extensions, deletions, changes) from some other pre-existing class.
CLOS Generalizes that to "... from some other pre-existing (required for
instance instantiation) class or classes".

>The ideal object-oriented language would:
>1) Have user-definable classes.
CLOS satisfies this requirement - methods may be specified not only on
defined classes, but also built-in data types (ie. integers vs. floats vs.
complex vs. ratios ... etc) and even single values.

>2) Have class inheritance.
CLOS has this.  In addition, it allows inheritance from multiple
(possibly disjoint) classes.

>3) Allow function/operator overloading.
CLOS has this.  Any function may be specialized on any one or more of
its required arguments. (there is no difference between operator and
function in lisp.  Note that macros and special forms may not be
specialized).

>4) Be completely polymorphic.
>Smalltalk and Lisp are highly polymorphic.  Next is Objective-C and Prolog.
>Then C++, and last is Modula-2.
I would like to see the definition of "polymorphic" (for my own
education).

As mentioned somewhere above, CLOS has rejected the message
sending/passing syntax of most OOL's in favor of generic dispatching
(required by multiple argument dispatch): where in most OOLs, one might
say something like "(send <object> :do-something-message <argument>)",
you'd say "(do-something <object> <argument>)" in CLOS for equivalent
functionality.  In CLOS, however, you are allowed to specialize the
behavior of a "message" to be based on any (one or more) of the arguments
passed to the generic function.

Anyway - I expect that your (informed!) choice of OOP Language will
almost definitely follow your favorite philosophy of programming: if you
are most productive in C, C++ is right for you... if LISP, than CLOS.

Now, to close, I'll ask if anyone would like to comment on the seeming
inconsistency of C evolving into a higher-level language (via C++)?  At
OOPSLA last summer, we were amazed to hear C++ people talking about
adding garbage collection to the language!  I'd hate to see what people
think of as "C" turn into lisp-with-C-like-syntax.  The big win of C is
that it encorporates into a small language a number of very powerful
abstractions with low (or zero) performance cost.  Lets face it - if
speed were all I cared about, I'd use Fortran exclusively... but I
couldn't do without recursion for very long, so next choice is C.  If I
wanted limited OOP, I'd go for C++. Full dynamic environment? LISP. Full
dynamic OOP? CLOS!
  Does anyone have an opinion as to how far up the "ladder of
abstraction" C can be pushed without destroying its best features
(low-level expression = speed)?

dan@acates.UUCP (Dan Ford) (04/20/89)

In article <2602@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes:
>I would like to see comparisons of C++ vs. other object oriented languages
>such as:
>C++ vs. Modula2
>C++ vs. Lisp
>C++ vs. SmallTalk
>C++ vs. Prolog
>C++ vs. Objective C

I would add to the list Eiffel -- see comp.lang.eiffel.

Dan Ford    uunet!acates!dan
"You may not have stolen any eggs, but I get you've poached a few." Odd Bodkins

kobryn@esosun.UUCP (Cris Kobryn) (04/25/89)

In article <1022@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:

   . . .
   >The ideal object-oriented language would:
   >1) Have user-definable classes.
   >Lisp and Prolog  
   >permit the programmer to define his own class mechanism.  There are versions 
   >that come with classes built in.

   >Smalltalk and Lisp are highly polymorphic.  Next is Objective-C and Prolog.
   >Then C++, and last is Modula-2.

   Look, will you _please_ take Prolog out of this discussion?
   Prolog is not an object-oriented language.  It makes no pretence of being
   an object-oriented language.  It goes out of its way NOT to be an object-
   oriented language.  

Consider C&M's intro sentence (Ch. 1) in "Programming in Prolog":

	   Prolog is a computer programming language that is used for solving
	problems that involve *objects* and the *relationships* between
 	objects....

   Being paid by a Prolog company, I naturally think that
   Prolog is super-wonderful (logic is God and Warren is its prophet), but
   anyone who buys a Prolog system in the expectation that s/he will find it
   possible to define objects in it is in for a big disappointment.

It is more than *possible* to define objects in Prolog.  Consider Quintus'
ProWINDOWS, an OOPS for UI devlopment:  it supports abstraction, inheritance, 
polymorphism and message-passing.  (If you need a technical POC at Quintus,
I'd be glad to oblige ;->)

-- Cris Kobryn

rai@wilbury.uucp (Nitin Rai) (04/26/89)

In article <461@esosun.UUCP> kobryn@esosun.UUCP (Cris Kobryn) writes:
>It is more than *possible* to define objects in Prolog.  Consider Quintus'
>ProWINDOWS, an OOPS for UI devlopment:  it supports abstraction, inheritance, 
>polymorphism and message-passing.  (If you need a technical POC at Quintus,
>I'd be glad to oblige ;->)
>
>-- Cris Kobryn

No you are not defining objects in Prolog. ProWINDOWS is a separate process
(C process) and you can create, manipulate and destroy "Objects" defined
in ProWINDOWS through prolog. The objects are ProWINDOWS objects that accessible
through prolog. It doesn't make Quintus Prolog object oriented in any way.

Nitin


{ "If Prolog is god and Warren is its prophet, then O'Keefe is its messiah!:-) }