<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I knew there would be some old-dog out there that had a few tricks up his sleeve. Sadly, I am post-Genera generation. Thanks for chiming in there Scott. Gives me a lot to chew on.<div class=""><br class=""></div><div class="">- DM</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">On Aug 26, 2016, at 06:17, Scott McKay <<a href="mailto:swmckay@gmail.com" class="">swmckay@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">From my perspective, there are two orthogonal things going on here:<div class=""> 1. The idea of a "resource" with a well-defined protocol for allocation, initialization,</div><div class=""> deinitialization, and deallocation. Genera (and CLIM) had macrology for this:</div><div class=""> <font face="monospace, monospace" class="">defresource</font> to define a resource, <font face="monospace, monospace" class="">using-resource</font> to use it in a "safe"</div><div class=""> way such that all those things happened in order.</div><div class=""> 2. Having <font face="monospace, monospace" class="">let</font> behave like <font face="monospace, monospace" class="">using-resource</font><font face="arial, helvetica, sans-serif" class="">.</font></div><div class=""><br class=""></div><div class="">It would be perfectly simple to write a <font face="monospace, monospace" class="">let</font> macro that shadows <font face="monospace, monospace" class="">cl:let</font>, which</div><div class="">tracks allocation/initialization of resources, evaluates the body, and then calls</div><div class="">the deinitializer/deallocator. How you implement "resources" is up to you. :-)</div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Fri, Aug 26, 2016 at 7:52 AM, David McClain <span dir="ltr" class=""><<a href="mailto:dbm@refined-audiometrics.com" target="_blank" class="">dbm@refined-audiometrics.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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.<br class="">
<br class="">
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.<br class="">
<br class="">
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.<br class="">
<br class="">
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.<br class="">
<br class="">
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.<br class="">
<br class="">
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.<br class="">
<br class="">
So then we have to invent reference counting to be sure we don’t destroy a shared object pointer too soon.<br class="">
<br class="">
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.<br class="">
<span class="HOEnZb"><font color="#888888" class=""><br class="">
- DM<br class="">
</font></span><div class="HOEnZb"><div class="h5"><br class="">
<br class="">
> On Aug 25, 2016, at 22:42, Nick Levine <<a href="mailto:nick@nicklevine.org" class="">nick@nicklevine.org</a>> wrote:<br class="">
><br class="">
> Would finalisers do the trick?<br class="">
><br class="">
> Not part of the language itself, but many implementations support them.<br class="">
><br class="">
> 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.<br class="">
><br class="">
> - nick<br class="">
><br class="">
<br class="">
<br class="">
</div></div></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div></body></html>