From: smh@franz.com (Steve Haflich)
Subject: Re: How to neatly destroy instances?
Organization: The Ohio State University Department of Computer and Information Science
Date: Tue, 13 Oct 1992 04:32:10 GMT

> From: simon@lia.di.epfl.ch (Simon Leinen)
> 
>    Now, one thing that didn't happen in X3J13's revision of Common
>    Lisp was changes to garbage collection to support such things 
>    as finalization and weak pointers.  I think it was reasonable
>    not to do this, but I want to add my voice to those saying
>    "we want it" in the hope that implementors will be influenced.
> 
> Me too! (But maybe it's too late to complain to vendors :-) Allegro CL
> 4.1 has "weak vectors" and finalization, the Lucid 4.1 announcement
> talks about new features called "weak pointers and finalization".
> (Maybe this is going to be the next major application of #+/#- :-)
> 
>    I'm not really sure finalization is a good idea though.
> 
> Why not? Let me guess: Programs that rely on finalization methods a
> lot will be difficult to debug ...

We now have a little customer experience with finalizations, perhaps
just enough to make some useful comment:

A finalization is a function that will be called when (actually, just
before) an object becomes garbage and will be abandoned by the
scavenger on the next scavenge (provided, of course, running the
finalization doesn't cause the object to become live again).
Finalizations are quite useful and appropriate for a few very kinds of
purposes.  Generally these involve explicit ``system programming''
tasks such resource management for very large or otherwise expensive
objects, or objects that require some active cleanup of non-Lisp
resources, such as closing a Unix stream if inadvertently abandoned.

However, IMHO finalizations are _not_ appropriate anywhere in an
application that directly involves the application's computational
algorithms, as distinct from its low-level system-programming
interface.  (I'm not happy with the way I'm making this artificial
distinction between a program's algorithm and it's underlying system
interface -- but "you know what I mean.")  Difficulties arise when
application programmer tries to build on assumptions about the precise
time a finalization will be run, or the order.  Although all garbage
collectors I know of are quite reliable about abandoning objects that
have become garbage -- CL implementations almost never have memory
leaks like certain other languages we all know -- but the _time_ that
an object becomes garbage can be affected in very unobvious ways by
compilation strategy -- both high-level code rewriting and low-level
machine architectures.  For example, although an object can
technically be garbage in the sense that lisp calculation can never
again see it, there may be a pointer to the object left in some
lexical variable or machine register which is subsequently saved to
the stack.  It is impractical for the garbage collector (which, after
all, wants to run as fast as it can) to determine whether a random
machine register saved in some random stack frame is indeed a live or
dead.  Alternatively, compiled code could null out each register every
time it becomes dead; but this would cost cycles, and most
applications don't want to pay the price.

I don't think finalizations belong in the language standard -- they
are a non-standard agreement between application writer and the
implementation's storage management system.  It is still conceivable
that memory architectures might someday change and someone might
implement a lisp that doesn't need a gc because it can arbitrarily
grow memory.  Although fanciful, such an implementation shouldn't be
precluded, therefore the very concept of garbage itself doesn't belong
anywhere in the language spec -- except tangentially with things like
the DYNAMIC-EXTENT declaration.  It provides advice to the compiler
and doesn't add any semantic content to the language.

Anyway, my advice is never to use finalizations for _computational_
effect.
Newsgroups: comp.lang.clos,comp.lang.lisp