On Tue, Aug 27, 2002 at 01:23:50PM -0700, Sean O'Rourke wrote: > On Tue, 27 Aug 2002, Mike Lambert wrote: > > Is there still a need for determinstic destruction, even in light of the > > alternative approaches mentioned above? > > Yes, if the destruction of the resource is itself important to the > program. For example, one way to do exception-safe locks in C++ is to > have a stack-allocated object whose constructor acquires the lock, and > whose destructor unlocks it. I'm not sure if this is a paradigm we want > to support, but it's something to think about.
On a very similar note, I've used them for logging timing statistics. Something like sub processRequest { my $timer = Timer->start("query"); } would produce <timestamp> START query <timestamp> STOP query, 0.26 seconds elapsed no matter how processRequest exited. I have done various other similar things. Someone (Abigail?) wrote a CPAN module to do arbitrary actions this way; we could check with her to figure out what they're useful for. So we've identified two general (overlapping) classes of uses: those that are purely scope-related (and can be implemented with a stack), and those that are used to control allocation of a scarce resource, like file descriptors (or memory!). The first, stack ops, could be implemented by making it illegal to keep external references to those objects, and then just checking them at either every scope exit, or at points manually inserted by the compiler. Or maybe a hybrid is possible -- you can keep an external reference, but you lose the guarantee of prompt finalization if you do so. I haven't thought that one through. The second, scarce resource management, can be handled the same way as regular memory garbage collection: only check on allocations, and only when you're in danger of using too much. Although many of the examples of this sort of use bother me, for one reason -- what happens if the destruction fails? free() won't, but close() often will, and finalization might happen far from code that could handle the failure properly. Could we maybe keep a continuation in these objects, and throw the exception from there? (Does that even make sense? My brain hurts.) It could easily be too late by then, anyway, and maybe the answer is just "if you need to handle finalization failure, then do it explicitly!"