[comp.lang.c++] Objective C: Flame Fodder

jans@tekgvs.LABS.TEK.COM (Jan Steinman) (04/27/89)

I've been playing with a loaned NeXT machine, and am *extremely* impressed with 
it's graphics performance.  (Optical disk performance is another story!)  It is 
much faster than Interviews based code in X11.

Some of the demo code has source with it, and is most certainly Objective C.  
This leads me to think that, well sure, the implementation of C++ is optimized 
for execution efficiency, but who cares?  The NeXT user interface puts X11 to 
shame -- is that the result of Objective C having better efficiency in the 
*coding* phase, versus the *execution* phase?

Does anyone know to what degree the NeXT graphics system code is written in 
Objective C?  If a large proportion of it is Objective C, then I think the 
relative performance issue is a non-issue.

:::::: Jan Steinman - N7JDB		   Electronic Systems Laboratory ::::::
:::::: jans@tekgvs.LABS.TEK.COM	      Box 500, MS 50-370 (w)503/627-5881 ::::::
:::::: jsteinma@caip.RUTGERS.EDU     Beaverton, OR 97077 (h)503/657-7703 ::::::

jima@hplsla.HP.COM (Jim Adcock) (04/28/89)

> Some of the demo code has source with it, and is most certainly Objective C.  
> This leads me to think that, well sure, the implementation of C++ is optimized 
> for execution efficiency, but who cares?  The NeXT user interface puts X11 to 
> shame -- is that the result of Objective C having better efficiency in the 
> *coding* phase, versus the *execution* phase?
> 
> Does anyone know to what degree the NeXT graphics system code is written in 
> Objective C?  If a large proportion of it is Objective C, then I think the 
> relative performance issue is a non-issue.

I think what you will find is that ObjC is being used as a veneer over some
very fast code written in asm and standard C.  If an ObjC message causes
the execution of a few thousand asm or straight-C statements, as can easily
happen in the execution of a high level graphics call, then the messaging 
overhead becomes a don't-care.

Other approaches that work just as fast in the same situation are: purely
interpreted languages [which have the advantage of not mixing two syntaxes
together], applications that make window environments interactively, etc.

The goal of C++ is to make OOP affordable across the whole range of
programming activities, not just "high level" programming.  For very
high level programming, C++ is presently at some disadvantage for not
having an integrated development environment.  It may make up for this
disadvantage by being the fastest OOPL, and the most widely available.
It may be worthwhile to put up with less in the way of a development 
environment in order to have the code that runs the fastest, and is
available on more machines than anyone else.

jima@hplsla.HP.COM (Jim Adcock) (04/29/89)

> In article <6590099@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes:
> > ...
> >To me, C++ is object-oriented, and ObjC isn't.
> > ...
> 
> From my understanding of Obj-C (from reading Brad Cox's "Object Oriented
> Programming"), there is no reason you can't add the [] messages to C++,
> getting Objective-C++. Then you have the best (and worst) of both worlds.
> [p.s. IMHO Obj-C is more like Smalltalk so "objected-oriented" but that
>       is by-the-by] ... cheers, matt.

Well, as one who comes from an ObjC enviroment, with on the order of 100
man-years invested by my local organization in ObjC, many people here have
certainly entertained the thought.

And the answer is, practically speaking, you cannot do it.

ObjC is a compiler that accepts straight-C plus 
ObjC [myObject with: junk andmore: junk]
syntax for messaging and "compiles" the result to straight-C code.

C++ is a compiler that accepts straight-C plus C++ extensions
to the syntax.

Neither accepts the other's extensions to C syntax.  So to run
one into the other you'd be restricted to using the straight-C
common subset used by both langauges.  If you're lucky.  In
which case you've gain nothing.

My answer was to try to salvage ObjC code [where ObjC development
gave us something actually reuseable] by writing a translation
aid that turns ObjC's:

[myObject with: junk andmore: junk]

into a C++

myObject->with_andmore(junk, junk)

[in real-world examples the name translation usually comes out prettier
 than this :-]

To perform this translation reliably, you have to parse the language,
textual substitution doesn't hack it.  So the translation aid ends up
looking a lot like the front end of a full compiler.  Except my 
translator [at least] doesn't understand the semantics, typing, etc
of objects, so the translator only saves maybe 90% of the effort
one would have to put into a totally manual translation effort.

Initially, coming from an ObjC environment, I felt:

[myObject dosomethingwith: this and: that]

was a prettier syntax than C++'s

myObject->dosomething(this, that)

but ObjC programmers [hackers?] write a lot of code like:

[myObject dosomethingwith: this and: that and: thenextthing and: more and: more and: more]

which really isn't object oriented programming -- its really functional programming.

C++ syntax, and low messaging cost, encourages programmers to only use zero, one
or two parameters to a method.  So in C++, you "set up" your object, then ask it
to perform a task based on its state, rather than passing in everything as a parameter.

And the C++ syntax is proving to be much more flexible.  People are taking C++
in an incredible variety of directions -- and for the vast majority of cases,
C++ syntax is up to the job.

jima@hplsla.HP.COM (Jim Adcock) (05/06/89)

> 	Programmer A is building a MailBox class, which must be able to 
> 	mail any kind of office object (whether existing now or in the future).
> 	He chooses to have MailBox inherit functionality from Collection, which
> 	inherits from Object. 
> 
> 	Programmer B is building an Envelope class, which like MailBox must
> 	be able to contain any number of any kind of office Form. He chooses 
> 	to have Envelope inherit collection functionality from Collection.
> 
> 	Programmer C is building a family of Form classes. For his own good
> 	and sufficient reasons, he chooses not to inherit functionality from
> 	Collection, but instead defiles an abstract Form class with separate
> 	subclasses for Memo, BusinessLetter, etc.

In any language, for a given business class to be mailed, that class must
meet the expectations of the MailBox class.  Presumably the MailBox class
needs to know about the size of an object to be mailed, its class, a
way to turn that object into a mailable form -- such as machine independent
ascii representations etc.  In any langauge, if the needs of the MailBox
are not met, the program will bomb, either at compile time, or (god forbid)
while a customer is running the program.

One way to have the needs of the MailBox met are for the writer of the
MailBox to write a set of specification of the functionality an object
needs in order to mailable.  Certainly, if the object's class is already 
written, it is unlikely to meet the needs of a MailBox written later.  So
the class must be either rewritten or augmented.  In any language, if
a class happens [blind luck] to have the functionality MailBox needs --
then the job is done before it is started.

One simple, clean way to solve this problem in C++ is to use multiple
inheritence to add the functionality the MailBox needs, regardless
of the class hierarchy that a class originally inherited from.

Thus C++ allows people to create differing class hierarchies, with
totally differing goals, philosophies, optimizations, and weaknesses;
and to combine these strength and weaknesses at later times, resolving
conflicts where they arise.  

Rather than pretending one person's class hierarchy is the solution 
to the whole world's problems.

jima@hplsla.HP.COM (Jim Adcock) (05/08/89)

Regards Brian's comments on the 'virtues' of not 
type checking:

When I was programming in ObjC, I found the lack of
type checking to be a curse, rather than a blessing.

I'd write a class with a method say 'doSomething:'
that takes an int parameter and returns a double
result, and someone else would quite unbeknownst
to me accidentally write a method also called
'doSomething:' taking an id as a parameter and
returning an int, and all of a sudden my compiles
would stop working.  Ouch!  And then you'd spend
a day running around the lab trying to find out
who writing what class came up with a method
name returning a different type than your method.

Eventually, to get around these problems, many
programmers took to writing method and object names like:

aCertainClass objectOfaCertainClass;

anInt =[objectOfaCertainClass certainClassMethodreturningInttakinganId: anOtherObject]

-- Well I exxxagerate, but the point being, without overloading and disambiguizing
names based on parameter types, people were forced to come up with deliberately
weird and ugly method names in order to avoid conflicting accidentally with
someone elses names.

Maybe in Smalltalk, where everything really is an object, this would be
less of a pain.  But it ObjC, where primitives (int, char, double, float, etc)
have a type and composites don't have a type, you were forced to do weird
name encoding to avoid conflicts.

Of course, cfront just does all these weird name encodings for you, automatically!
:-)  But at least only the linker has to look at the weird names, not you or 
your fellow programmers.

I think Brian's complaints have some merit in the absence of multiple
inheritence.  But with multiple inheritence you can easily add the compatibility
necessary to use your classes with someone else's classes.  Only when there
are direct method name conflicts would extra effort have to into resolving the
conflict. [Not hard -- just requires writing a method.]  More importantly,
with multiple inheritence each and every class is NOT forced to have  
a certain collection of a couple dozen basic methods -- and the underlying
store requirements in each object that those methods imply.

So a complex number in C++ can consist solely of two doubles -- if you
want to use a complex number in JoBlow's whizbang object class hierarchy
scheme, you can glue Jo's stuff to the complex stuff using multiple
inheritence -- you are not forced to buy into Jo's scheme from day
one and for all eternity.

So for example, I'm not totally enamored with streams, so sometimes I
don't use them.....

I'm not crazy about Gorlan's approach, so sometimes I don't use his
stuff -- other times I use them...

In C++ you get the choice, the control over what software you write,
and what software you use.