[gclist] Guardians

Jerry Leichter leichter@smarts.com
Thu, 10 Apr 1997 15:30:04 -0400


[Usefulness of finalizers for files backing "ropes" in an editor.]

I don't think we actually disagree.  I'm saying thatt, *in general*, using finalizers to (attempt to) implement an abstraction on 
top of files which hides errors, lack of file descriptors, etc., will fail.  
You've described a specialized example, ropes, which open files read-only, so 
don't have to deal with asynchronous errors, can afford to close a file to 
return the descriptor in times of need, then later open it again and position 
back to where they were, etc.  (Not that finalizers would help you implement the 
latter.)

I don't disagree that finalizers are a useful tool.  But they are a tool that 
should be used relatively rarely, in well-defined situations.  Problems arise 
when people try to elevate finalizers to a central role.  Perhaps a good analogy 
is to exception handling.  It's a wonderful program structuring tool, and works 
extremely well in its intended role as a way of dealing with rare conditions.  
It's certainly possible to use it as a basic program design technique, analogous 
perhaps to failure in SNOBOL4 and Icon.  You can come up with some really 
elegant expressions of algorithms that way.  But the resulting code will run 
like a dog, since exception handling is slow in just about every implementation.

There's even an analogue to this at a lower level.  One can write some very 
elegant numerical algorithms that rely on IEEE FP arithmetic, and in particular 
on its handling of various exceptional conditions.  Bad idea.  Real hardware 
rarely implements the full model; exceptional conditions are punted to software, 
and will be very slow.  Fine for the typical, intended uses; killers when they 
end up in the main line of execution.

The problem with finalizers isn't *exactly* like the problem with exceptions.  
It's not that finalizers are, or have to be, inefficient.  Rather, it's that the 
actual abstract properties they can safely be assumed to have are pretty 
limited.  Safe?  Sure?  Prompt?  Which do you want?  What will you pay for them?

As they say, when all you have is a hammer, everything looks like a nail.  The 
typical modern programming language provides all sorts of structuring tools 
appropriate to different uses.  Pick any one detailed semantics for finalizers - 
with weak guarantees and high performance, or strong guarantees and a great deal 
of overhead - and what you get isn't a hammer; it's a single hex key, say.  
Great at what it does; you *could* use it as a punch, a pry, perhaps even as a 
hammer - but it's not really *good* at any of those things.

							-- Jerry

PS:  The old, dead pre-X VMS window system, VWS, used an I/O channle *per 
window*.  This had all sorts of nice properties in the interface you ended up 
with - after all, a window *is* a kind of virtualized I/O device, isn't it - but 
could be used on VMS only because the number of I/O channels a process could 
open could cheaply be set very large - typically in the thousands, for systems 
running VWS.  Such an interface would never have flown on Unix, which in those 
days typically allowed 20 file descriptors per process, and today usually allows 
on the order of 64 by default, and perhaps 1024 maximum.  So, yes, file 
descriptors are *still* precious resources, in that you have to think about how 
you are using them in the way we used to have to think about memory - but 
generally no longer do.  -- J