Detecting at runtime when bindings go out of scope?

Scott McKay swmckay at gmail.com
Fri Aug 26 13:17:49 UTC 2016


>From my perspective, there are two orthogonal things going on here:
 1. The idea of a "resource" with a well-defined protocol for allocation,
initialization,
   deinitialization, and deallocation. Genera (and CLIM) had macrology for
this:
   defresource to define a resource, using-resource to use it in a "safe"
   way such that all those things happened in order.
 2. Having let behave like using-resource.

It would be perfectly simple to write a let macro that shadows cl:let, which
tracks allocation/initialization of resources, evaluates the body, and then
calls
the deinitializer/deallocator. How you implement "resources" is up to you.
:-)


On Fri, Aug 26, 2016 at 7:52 AM, David McClain <dbm at refined-audiometrics.com
> wrote:

> 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
> >
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/pro/attachments/20160826/e90826d0/attachment.html>


More information about the pro mailing list