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 > On 26 Aug 2016, at 06:38, David McClain <d...@refined-audiometrics.com> wrote: > > HI David, > > Yes, I think you put your finger on it. I had this odd sensation in the back > of my mind, that I had actually seen this behavior before. And then I > remembered C++-land. Automatic destructors called at function exit — a sort > of leaving scope operation. > > So yes, you understand correctly. And the question arises, is there anything > down in the bowels of Lisp, some little known feature, that can indicate > scope exit? > > Your scode / unscope fits pretty well, but so does when - unwind-protect. I > don’t see a lot of difference between them, except that you have a generic > de-scoping function. > > What I was hoping for was something during compile time that would be called > on scope-exit of bound variables. Something we might hook into. > > [ BTW, after completing that article I referenced, I had a deep sense of > relief that I don’t live in C/C++ land very much anymore. I truly appreciate > whatever Lisp has to offer. ] > > - DM > > >> On Aug 25, 2016, at 20:13, David Holz <david.h...@grindwork.com> wrote: >> >> On 08/25/2016 06:20 PM, David McClain wrote: >>> What I’m wondering about is being able to declare an item, a special kind >>> of Constructor parameter, which refers to a system resource that needs >>> scavenging, such that I could forego the WITH- formalism? Maybe I’m asking >>> for too much here… how would we ever detect the item being stored? We’d >>> need reference counting, and I tend to dislike that approach very much.. >>> >>> Anyone ever seen a system for resource reclamation that is better than >>> WITH- and UNWIND-PROTECT? >>> >>> - DM >> >> If I'm understanding correctly, your ideal would be something like this: >> >> (let ((channel (make-channel ...))) >> (do-stuff channel) >> (do-other-stuff channel)) >> >> and at the end of the lexical scope, due to the fact that the channel object >> has something special done to it during construction, it automatically calls >> disposal routines of the channel right at that point? >> >> I think that's going to be tough, as well as ambiguous. You don't want >> every lexical binding that happens to bind a channel object to destroy it at >> the end of the scope, a la (let ((ch (channel-slot-accessor obj))) ...). >> You want only those which "locally create" an object (by some >> distinguishable means) to destroy it at the end. I personally think that >> would imply some form indicating a specific scope type that determines an >> object lifetime, which really does boil back down to with-* forms again. It >> is the scope itself that rules the object lifetime, not the other way around. >> >> Examples from other languages would be C++ RAII (which is a usage style, not >> exactly an explicit feature), and Python's context managers. I think the >> Python example would be the closest to a style that would fit a CL >> abstraction, and this is actually something I've thought about for quite >> some time. >> >> This is off the cuff, but abstracting out the with-* style seems to boil >> down pretty neatly: >> >> (defmacro scope (var creation-form &body body) >> `(let ((,var ,creation-form)) >> (unwind-protect (progn ,@body) >> (unscope ,var))) >> >> (defgeneric unscope (obj)) >> >> So along with the standard construction form of an object, you'd define an >> UNSCOPE method for an instance of it, and the abstract (scope ch >> (make-channel ...) ...body...) should Just Work™. It's still built on top >> of UNWIND-PROTECT, but you as the programmer need not worry about it >> yourself. >> >> -- >> David Holz >> Director, Grindwork Corporation >> http://www.grindwork.com/ > > >