[Python-Dev] Tackling circular dependencies in 2.0?

Tim Peters tim_one@email.msn.com
Tue, 21 Sep 1999 02:11:00 -0400


[Skip Montanaro]
> I think in Python 2.0 it would be nice to have some way to
> reclaim circular dependencies without the programmer explicitly
> having to do something ...

This was debated (again) at great length on c.l.py just a few months ago.
Guido chimed in with a proposal to keep track of only the dicts that have
been allocated, and now and again mark everything reachable from the root
set and nuke whatever dicts don't end up marked.  Cycles involving dicts
would get reclaimed this way, but not cycles not involving dicts.  The
approach to destructors for objects in cycles was "tough -- they don't get
called".  What to do about destructors for objects that are not themselves
involved in cycles but are reachable only from dead cycles (so are in fact
dead too) wasn't addressed.  Seemed possible that stuff reachable from
ordinary dicts (not in a cycle, and neither reachable from a cycle) would
behave differently than today, since the "list of all dicts" may keep the
stuff artificially alive until the next mark+sweep, even if the refcount on
the stuff fell to zero; there's probably an OK way around that, though.

Anyway, Guido was aiming for the minimal changes that could possibly do real
good.  It didn't pretend to reclaim all cycles, and was (IMO) too eager to
punt on the hard issues (the combo of cycles, destructors and resurrection
is a god-awful mess, even in theory; Scheme uses callbacks to dump the
problems back on the users Java has incredibily elaborate rules that are
both bulletproof and unusable; the Boehm collector lets objects with
destructors that are in cycles simply leak, rather than do a wrong thing;
Stroustrup has flip-flopped and most recently argued for Guido's "reclaim
the memory but don't call the destructors" approach, but a member of the C++
committee told me he's overwhelmingly opposed on this one (I know I would
oppose it)).

In any case, nothing has come of it, and no easy principled solution is in
sight.  OTOH, if Guido balks at explaining what "__" means to 12-year-olds,
wait until he tries to explain immortal cyclic trash <wink>.

Perl scores points for its brute-force end-of-thread M&S, but I believe
complex user-level data structures are much rarer in Perl, simply due to the
clumsiness of the syntax and explicit reference model.  Perl's version of
"nested functions" don't actually nest (all "def"s are floated to the top
level by the compiler, regardless of how deeply they're nested), so Perl's
lexical closures don't create cyclic trash either (well, they do, but in the
same sense there's a cycle between a Python module namespace and the
functions in that module -- Perl also special-cases the snot out of those
and busts those cycles by brute force).

So there you go!  It needs to be solved and nobody has a clue <wink>.

if-java-hype-hadn't-suffered-exponential-decay-we-could-have-
    dumped-it-on-the-jvm-by-now-ly y'rs  - tim