fork()

Tim Peters tim_one at email.msn.com
Thu Jun 17 01:58:13 EDT 1999


[Hisao Suzuki and Tim, jockeying over new/delete in C++ vs __del__ in
Python,
 and their relation to cycles and some Stroustrup quotes]

[Hisao]
> ...
> You miss the point.

Could be.  Expect it's really that I disagree with it, though.  I agree that
(barring pathologies) the only a way an object is immortal in C++ is if it's
explicitly new'ed but never explicitly delete'd, and that the only way an
object is immortal in Python (make that CPython, & make that today) is if
it's in a cycle.
You want to infer something from that, while I think the languages are so
different that trying to read anything into it is like trying to see animal
figures in the passing clouds <wink -- but, yes, your "It sounds like a
theoretical nonsense.">.

> ...
> If an object is part of a cycle, the object will never lose the
> reference(s) to it.  So the phrase `(be) never deleted' for C++
> can be safely translated as `(be) part of cycles' for Python.
> You see?

To me, that merely describes the conditions under which the respective
languages treat an object as immortal today.  It makes good sense for
Stroustrup to say that in C++ a garbage collector shouldn't invoke the
finalizer for its flavor of immortal objects, but he's not arguing that
position *because* they're immortal today, but instead because explictly
new'ed objects never have their finalizer invoked in C++ unless explicitly
delete'd, and GC is not explicit delete'tion.  Python has no such rules, so
the core of his argument doesn't apply to Python without more strain than I
can swallow <0.9 wink>.

> | Further the C++ 3rd Ed. says:
> |    "It is possible to design a garbage collector to invoke the
> |     destructors for objects that have been specifically
> |     registered' with the collector.  However, there is no
> |     standard way of `registering' objects.  Note that it is
> |     always important to destroy objects in an order that ensures
> |     that the destructor for one object doesn't refer to an
> |     object that has been previously destroyed.  Such ordering
> |     isn't easily achieved by a garbage collector without help
> |     from the programmer."

[Tim]
>> Java solved that one -- for all the good it did <wink>.

[Hisao]
> Are you referring to java.lang.ref.PhantomReference of Java2?

No.

> Otherwise you wholly miss the point.

Whose point <wink>?  Java has always guaranteed to "destroy objects in an
order that ensures that the destructor for one object doesn't refer to an
object that has been previously destroyed", and indeed "without help from
the programmer".  So by "Java solved that one" I meant it satisfactorily
addressed the points made in the quote.  That doesn't mean there aren't
other points to be made, but since the quote you gave didn't make any other
points I don't feel bad about commenting on the points it did make <wink>.

> The traditional mechanism of finalization in Java serves as only a
> safety net at _best_.

Sure.  It can't be faulted for any of the points *Stroustrup* made, though.

> ...
> The idea of guardians is not so particular to Scheme.  It might
> be safe to say that Scheme is a language that happened to be
> used.  Needless to say, it is important to keep _Python_ simple,
> handy, and consistent.

Yes, except I'd rather Python be consistent with its own object semantics
than with isolated portions of C++'s; and despite their frequent happy
coexistence, "simple" for the user is not always "simple" for the
implementation.

> ...
> However, the programmer often knows the expected refcount of the
> object or the aggregation object of several objects when it
> becomes unreachable from any other (aggregation of) objects.
> Usually (though not always) he/she can pass the expected
> refcount to the guardian.

Afraid not!  refcounts in Python are often unintuitive:

D:\Python>python
Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import sys
>>> sys.getrefcount(3)
8
>>> sys.getrefcount("Suzuki")
4
>>> sys.getrefcount("Hisao Suzuki")
2
>>> sys.getrefcount(sys)
5
>>>

People use getrefcount at their own risk, and the specific values returned
are not bound to remain the same from one release to the next, or even one
run to the next (toss in a thread or two, and they can bounce around
seemingly "at random" even within a single run).  The refcounts are there
for the convenience of the implementation, not the user; so this isn't a
foundation on which to build anything at the user level (although some
people do, and some of those even live long enough to regret it <0.9 wink>).

> ...
> And it is our usual practice to make prototypes in Python first,
> if possible, to experiment on some ideas, isn't it? :-)

Definitely.  In this case, though, it's probably easier to modify the Python
source code <0.5 wink>.

curmudgeonly y'rs  - tim






More information about the Python-list mailing list