[comp.lang.eiffel] Eiffel vs. C++ -- Let's drop the garbage collection arguments

cline@sun.soe.clarkson.edu (Marshall Cline) (06/10/89)

In article <1021@krafla.rhi.hi.is> snorri@rhi.hi.is (Snorri Agnarsson) writes:

>From article <77300029@p.cs.uiuc.edu>, by johnson@p.cs.uiuc.edu (Ralph Johnson):

>>>Written  6:48 pm  Jun  4, 1989 by bertrand@eiffel.com (Bertrand Meyers):

>>>Garbage collection
>> This is both a major advantage and disadvantage.  Would you advise
>> us writing our operating system in Eiffel instead of C++?  What
>> impact does your garbage collector have on real-time software?

>In my opinion garbage collection is the single most useful feature
>of a programming language.....
>....  Consider the following C function:                  [...deleted...]
>If C had garbage collection we could write code such as:  [...deleted...]
>Instead we have to write as follows:                      [...deleted...]

I'm going to *TRY* not to take sides in the war over the value of GC.
I **AM** going to say that the line of thinking is getting *OUT*OF*HAND*!!

The original poster (Bertrand Meyers) said he liked GC for such-in-such
a problem.  The respondent (Ralph Johnson) said real-time software wasn't
suited for GC.  Now we get Snorri Agnarsson saying that he can come up
with an example where GC is useful.  WAKE UP FOLKS!  GC *IS* a useful
feature *SOMETIMES*.  It *MAY* not be a useful feature *ALL* the time!

The argument is getting WAY off course.  It's simply not true that:
	"Language X is better than Y *ALL* the time because
	 it has feature Z which is useful *SOME* of the time".

>It is often said that garbage collection is too costly, but I suggest
>that in the above example the solution with garbage collection is
>probably more efficient, both in programmer effort AND in
>the speed of the resulting program.  By the way, if garbage collection
>is too expensive, how about 'malloc' and 'free'?  Do you think those
>routines are less expensive?  Why do you think so?

No one in the C++ camp is saying that malloc()/free() are "free".
The point is simply that malloc()/free() is ***CONTROLLABLE***.
That's what C/C++ programmers like: TO BE IN CONTROL.
That't what Eiffel programmers DON'T like: TO BE FORCED TO CONTROL.

*NO* *NO* *NO* language is best under *ALL* *ALL* *ALL* circumstances.
Any sufficiently experienced computer professional chooses the best tool
to fit the job.

C++ folks don't want to be FORCED to have garbage collection ALL the time.
Eiffel folks don't want to be FORCED to memory allocation ALL the time.

C++ folks like the machine to do exactly what/when they tell it to.
Eiffel folks like a higher level of abstraction from the machine.

Conclusion: Let's drop the garbage collection argument from this discussion.

>>>Bertrand Meyer
>> Ralph Johnson
>Snorri Agnarsson
Marshall Cline
--
	________________________________________________________________
	Dr. Marshall P. Cline	ARPA:	cline@sun.soe.clarkson.edu
	ECE Department		UseNet:	uunet!sun.soe.clarkson.edu!cline
	Clarkson University	BitNet:	BH0W@CLUTX
	Potsdam, NY  13676	AT&T:	(315) 268-6591

campbell@redsox.bsw.com (Larry Campbell) (06/10/89)

In article <CLINE.89Jun9152152@sun.soe.clarkson.edu> cline@sun.soe.clarkson.edu (Marshall Cline) writes:
-
-C++ folks don't want to be FORCED to have garbage collection ALL the time.
-Eiffel folks don't want to be FORCED to memory allocation ALL the time.

The problem is, neither gets the choice.  In C++, you CANNOT have garbage
collection.  In Eiffel you cannot PREVENT garbage collection.  Why not
give the programmer a choice?

Contrast this with Modula-3, which provides GC, but makes it optional.
-- 
Larry Campbell                          The Boston Software Works, Inc.
campbell@bsw.com                        120 Fulton Street
wjh12!redsox!campbell                   Boston, MA 02146

marc@eiffel.UUCP (Jean-Marc Nerson) (06/11/89)

> .........
>No one in the C++ camp is saying that malloc()/free() are "free".
>The point is simply that malloc()/free() is ***CONTROLLABLE***.
>That's what C/C++ programmers like: TO BE IN CONTROL.
>That't what Eiffel programmers DON'T like: TO BE FORCED TO CONTROL.
> ..........
> ..........
>C++ folks don't want to be FORCED to have garbage collection ALL the time.
>Eiffel folks don't want to be FORCED to memory allocation ALL the time.
> ..........

	In Eiffel: 

	1) Object allocation is always under programmer's control
	since you know when you create a reference to an object.

		At execution time, the statement:
			obj.Create  [Create could have possible arguments]

		does 1 or 2 things:

		o Call memory allocation routines of the run-time
		system. [where sbrk() is used instead of malloc()].

		o Possibly execute the body of the Create procedure of the
		class obj is a instance of if it has been re-programmed 
		with some initialization statements.

	The only case when memory allocation is not under programmer's 
	control is for the creation of the first object of the system, 
	instance of the root (or main) class. One could imagine an 
	application consisting of only one single class with no object 
	creation at all except for the root object. 
	This is not an O-O programming style ...

	2) Garbage collection can be under programmer's control.
	
	o Garbage collection is a compilation option.

	o If the system is compiled and linked with the garbage collector,
	the default mechanism is quasi parallel and self adaptive. 
	There is also a way for the application to control it by inheriting 
	from a library class called MEMORY that provides operations 
	to turn it on and off or even to do a 'Lisp-like' full collection 
	if wanted.


------------------------------------------------------
Jean-Marc Nerson -- Interactive Software Engineering
marc@eiffel.com

sommar@enea.se (Erland Sommarskog) (06/12/89)

Larry Campbell (campbell@redsox.UUCP) writes:
>The problem is, neither gets the choice.  In C++, you CANNOT have garbage
>collection.  In Eiffel you cannot PREVENT garbage collection.  Why not
>give the programmer a choice?

I don't have my OOSC around at the moment, but far as I recall Eiffel
does give you a choice. You can turn off garbage collection if you
absolutely have to. And calls corresponding to manually free memory
are also available. But you are certainly not encouraged to use them.
My apologies if I'm wrong on this point.

I don't speak C++, but an object-oriented langauge without garbage
collection seem quite useless to me. Or rather: it's not really
an object-oriented langauge, just a more structured form of C.
-- 
Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se
Bowlers on strike!

marti@ethz.UUCP (Robert Marti) (06/12/89)

In article <778@redsox.bsw.com>, campbell@redsox.bsw.com (Larry Campbell) writes:
> In C++, you CANNOT have garbage collection.

Wrong.  You can redefine operator new to use a garbage collecting
allocator, for example the one written by Hans-Juergen Boehm and Alan
Demers, which is described in
    H.-J. Boehm, M. Weiser:  Garbage Collection in an Uncooperative
    Environment.  Software Practice & Experience, Sept. 1988,
    pp.807-820.
and available from the archive server at RICE University.

In release 2.0, you can even redefine operator new on a class per class
basis.

-- 
Robert Marti                      Phone:      +41 1 256 52 36
Institut fur Informationssysteme
ETH-Zentrum                       CSNET/ARPA: marti%inf.ethz.ch@relay.cs.net
CH-8092 Zurich, Switzerland       UUCP:       ...uunet!mcvax!ethz!marti

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

Is there anybody out there in net land who has used both C++ and Eiffel
for more than a year, on real world [commercial] projects, that can share
some practical experiences relating the two languages?

snorri@rhi.hi.is (Snorri Agnarsson) (06/13/89)

From article <CLINE.89Jun9152152@sun.soe.clarkson.edu>, by cline@sun.soe.clarkson.edu (Marshall Cline):
> No one in the C++ camp is saying that malloc()/free() are "free".
> The point is simply that malloc()/free() is ***CONTROLLABLE***.

You seem to be suggesting that malloc()/free() is more controllable than
malloc()/garbage collection.  If so, then in what sense??
Garbage collection can be time-consuming, of course, but so can free().
If you have a language with garbage collection, it is usually very easy
to ensure that no garbage collection gets performed in some critical
section by simply not allocating any memory.

> That's what C/C++ programmers like: TO BE IN CONTROL.
> That't what Eiffel programmers DON'T like: TO BE FORCED TO CONTROL.

I do not understand what you are trying to say.

> C++ folks don't want to be FORCED to have garbage collection ALL the time.

That's good since in most instances they don't have garbage collection any of
the time.
But maybe some of them would like to have garbage collection some of the time.

> Eiffel folks don't want to be FORCED to memory allocation ALL the time.

????????????

> Conclusion: Let's drop the garbage collection argument from this discussion.

If you think talking about garbage collection is a waste of bandwidth you
are certainly entitled to that opinion, but I do not have to agree with you.

> Marshall Cline


-- 
Snorri Agnarsson		|  Internet:	snorri@rhi.hi.is
Taeknigardur, Dunhaga 5		|  UUCP:	..!mcvax!hafro!rhi!snorri
IS-107 Reykjavik, ICELAND

bamcpherson@rose.waterloo.edu (Brent McPherson) (06/15/89)

In article <6590148@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes:
>> -C++ folks don't want to be FORCED to have garbage collection ALL the time.
>> -Eiffel folks don't want to be FORCED to memory allocation ALL the time.
>> 
>> The problem is, neither gets the choice.  In C++, you CANNOT have garbage
>> collection.  In Eiffel you cannot PREVENT garbage collection.  Why not
>> give the programmer a choice?

Wrong, Eiffel allows the user to turn GC on/off.

>
>Perhaps a harder [impossible?] problem is to create a GC that is easily
>portable to the wide variety of machines that C++ supports.  More modern 
>GCs tend to get involved with the virtual memory hardware in order to speed
>the scan for garbage.  Clearly these kinds of approaches are hard to port
>between machines.
>

It seems to me that GC in a language such as Eiffel is alot easier to
implement since there is no notion of a global variable. The program
starts at the root class and all active objects are objects that can
be reached from the root class. This is a simple tree structure (and
hence easier to traverse).

>
>Still, it would seem to be useful to have some kind of GC available for C++,
>if only to report on objects that programmers have lost track of.

Most people seem to have a rather narrow view of what garbage collection
should be used for. It is not to free objects that programmers
"lose track of".  In the hands of a competant programmer GC is a powerful
tool. Data structures can become more compact since different objects
may safely point to the same data. In C (and other languages with
no garbage collection) there is usually one reference per structure.
If the same data is needed in another structure then a new copy is made.
This allows memory to be released easily but is wasteful and slow.

One way in which I have used GC is to keep a fixed-size list of object
references (stored in Least Recently Used order). Objects is this list
could share common sub-structures with other objects in the system.
When the list became full, the Least Recently Used object would drop off 
(be removed) from the list. If the object or its components are no longer
referenced by other active objects in the system, they then become
candidates for GC.  This is a very easy way to keep a history list of
objects to avoid unecessary computation/disk access for frequently
used objects.

A program designed in this fashion will often outperform a
similar and more complicated C program (since it is a *smarter* program).


Conclusion:

Both GC and explicit free are useful. Structures
that are created/destroyed in a systematic manner are good candidates
for the latter scheme since the programmer knows when an object is
no longer referenced and may be freed. In complicated cases programmers
tend to make mistakes (ei. free used memory or create dangling references).
In these cases GC is the better choice. A wise programmer will use
all tools at their disposal to obtain the best solution to a given problem.

--
Brent McPherson                      bamcpherson@rose.waterloo.edu

nevin1@cbnewsc.ATT.COM (nevin.j.liber) (06/24/89)

In article <34@enea.se> sommar@enea.se (Erland Sommarskog) writes:

>I don't have my OOSC around at the moment, but far as I recall Eiffel
>does give you a choice. You can turn off garbage collection if you
>absolutely have to.

But doesn't this affect class (or whatever the equivalent of "class" is
in Eiffel) design?  I, for would, would design differently based on
whether there was GC or not.  Is this done globally or on a
class-by-class basis?  There are problems with either approach.  If it
is global, some classes may die because there is nothing reclaiming
memory.  If it is on a class-by-class basis, I have to avoid all
classes which might possibly use GC, or it really isn't "turned off"
for my class.
-- 
NEVIN ":-)" LIBER  AT&T Bell Laboratories  nevin1@ihlpb.ATT.COM  (312) 979-4751

nevin1@cbnewsc.ATT.COM (nevin.j.liber) (06/24/89)

In article <1026@krafla.rhi.hi.is> snorri@rhi.hi.is (Snorri Agnarsson) writes:

|You seem to be suggesting that malloc()/free() is more controllable than
|malloc()/garbage collection.  If so, then in what sense??
|Garbage collection can be time-consuming, of course, but so can free().

But free() is more predictable.  In many current schemes, you never
know exactly when GC will take place, or how long it will take.

|If you have a language with garbage collection, it is usually very easy
|to ensure that no garbage collection gets performed in some critical
|section by simply not allocating any memory.

What if I *need* to allocate memory in a critical section?  Stopping GC
for some-of-the-time is not a trivial issue.
-- 
NEVIN ":-)" LIBER  AT&T Bell Laboratories  nevin1@ihlpb.ATT.COM  (312) 979-4751

campbell@redsox.bsw.com (Larry Campbell) (07/22/89)

Apparently I was too terse for my own good.  When I said (simplistically)
that "C++ prevents GC and Eiffel mandates it", people jumped all over that
statement, insisting that you can graft GC onto C++ and you can turn GC off
in Eiffel.

What I should have said is that "there is no language support for GC in C++"
(true) even though by suitable hackery you can graft it in;  I've even seen
GC grafted onto plain old C.  In my opinion, this doesn't count;  since
there's no language support, if you expect to use it, you're nonportable.
(I haven't seen the C++ GC wart, but the C one required assembly language
and an intimate knowledge of stack frames and register contents.)

And while Eiffel apparently lets you temporarily disable and enable GC on
a global basis, this is not a very fine grain of control.

Modula-3, by contrast, allows you to decide on a type-by-type basis whether
objects of the type are to be GC'd or not.  This seems to me to be the best
solution.
-- 
Larry Campbell                          The Boston Software Works, Inc.
campbell@bsw.com                        120 Fulton Street
wjh12!redsox!campbell                   Boston, MA 02146

chase@Ozona.orc.olivetti.com (David Chase) (08/03/89)

In article <779@redsox.bsw.com> campbell@redsox.UUCP (Larry Campbell) writes:
>Modula-3, by contrast, allows you to decide on a type-by-type basis whether
>objects of the type are to be GC'd or not.  This seems to me to be the best
>solution.

To be fair, this is only somewhat the case.  In code that is
explicitly declared as UNSAFE you are allowed to choose on a
type-by-type basis whether or not objects are GC'd or not.  In
practice, most code should *not* be unsafe (though some very important
code will be unsafe), and writing unsafe code places a much greater
burden on the programmer.  It really isn't much different from writing
C, except that many more errors become the fault of the programmer,
and the run-time system is not really tuned to make life easy for the
author of unsafe code.

For example, if you store a pointer to garbage-collected memory in a
record field that is declared to be an INTEGER, the memory could be
reused.  That's a programmer error.  If you store a pointer to gc
memory at an unapproved offset (i.e., odd byte alignment), the memory
could be reused.  That's a programmer error.  If you write unsafe
code, then it is presumed (as so many C programmers are quick to
claim) that you know what you are doing.

David

nadkarni@ashok.dec.com (08/03/89)

In article <45901@oliveb.olivetti.com>, chase@Ozona.orc.olivetti.com (David Chase) writes...
>In article <779@redsox.bsw.com> campbell@redsox.UUCP (Larry Campbell) writes:
>>Modula-3, by contrast, allows you to decide on a type-by-type basis whether
>>objects of the type are to be GC'd or not.  This seems to me to be the best
>>solution.
> 
>To be fair, this is only somewhat the case.  In code that is
>explicitly declared as UNSAFE you are allowed to choose on a
>type-by-type basis whether or not objects are GC'd or not.  In
>
> [stuff deleted]
>David

Not true as far as I recall. If I remember the report correctly, you CAN decide
on a type by type basis whether to GC or not. The UNTRACED keyword is provided
for this purpose. This is true even for SAFE modules. What you might be
referring to is that untraced REFs can point to traced REFs (or is it the other
way around ?) only in UNSAFE modules.

Of course, I've done little more than glance through the language definition
so I might be wrong.

/Ashok