Detecting at runtime when bindings go out of scope?

David McClain dbm at refined-audiometrics.com
Fri Aug 26 11:52:35 UTC 2016


Yes, finalizers can sometimes work. I have those in place. But they are tricky. Suppose I hand off a local channel to another thread to utilize of communication between us. Now there are two copies of that channel pointer. So when my local use goes out of scope, there is still one copy in use, by that thread. And that thread is likely just hanging, waiting for something to come across that channel, that never will, since it just went out of scope from the sending side. Hence GC will never have the opportunity to finalize.

Instead, you have to invent contorted references to the channel that can be neutralized by the sender when it goes out of scope.  And I say contorted because these references have to be complex enough that the compiler won’t perform some stack optimization and produce an inadvertent secondary reference.

So, for example, it isn’t sufficient to make a reference to a channel as (list ch) / (car ch). That seems to become unwrapped at the receiver side by things like handler-case, ignore-errors. Rather you have to use a functional closure like (lambda () ch) / funcall. And now we’ve lost the symmetry of use on each side of the channel. 

Not only that, but now we have to understand Lisp implementation details that we never needed to know before. And so we likely aren’t semantically portable.

Secondly, as you mentioned, not all Lisp support finalization, or not very well. Lispworks does fine, but I find SBCL particularly weak in that you only get told about an object being scavenged after it has already happened. Hence you have to keep a display array and use indirect references in SBCL.

What I recall from C++ world is that the automatic destructor calls at scope exit only happen on stack allocated objects, not pointers. Makes sense, since pointers allow for the possibility of alias pointers all over the place. Well, that’s exactly the situation we have in most Lisps too. In fact there can be no such thing as a stack allocated object, even if it really is allocated on the stack.

So then we have to invent reference counting to be sure we don’t destroy a shared object pointer too soon.

What I’m asking for really isn’t safe in Lisp. The best we can do, it seems, is what David proposes with his Scope macro, or my WITH- / UNWIND-PROTECT.

- DM


> On Aug 25, 2016, at 22:42, Nick Levine <nick at nicklevine.org> wrote:
> 
> Would finalisers do the trick? 
> 
> Not part of the language itself, but many implementations support them. 
> 
> Various caveats apply. In particular you cannot guarantee when (or I guess whether) any particular resource will be finalised; only that the GC will get around to most resources in the fullness of time. So this solution might not meet your needs. 
> 
> - nick
> 




More information about the pro mailing list