i'd like to perform some actions on a particular entity after there are no longer any references to it, but before the garbage collector wipes its data out. i'm using this for an experiment with more "purely functional" gui abstractions. here is what i'd like to do:
(let [window (make-window width height)] ; A
(various-actions window)
(let [window (resize window new-width new-height)] ; B
(more-actions window))
(and-more-actions window)) ; C
at A a window instance is created with a width and height. eventually i want to change the window at B. the code treats this like an immutable action, but underneath the window will simply change to reflect the changes. actions performed on the A scope's window while the B scope's window exists (in case of multithreading) would not be allowed in some manner.
at C after we finish doing stuff at B and leave that let scope, the B window object will be unreferenced and garbage collected. but i want to signal the underlying window mechanism that it should roll back the B changes now, and accept A scope activity again. thus action at C will be as though B effects didn't happen.
as well, if the top level A window is no longer referenced, it should destruct itself in whatever manner before garbage collection.
i could possibly manage this by having make-window modify a global state which registers window references, but i'm not sure how to detect the point at which the B scope reference is lost. how can i check the references to a piece of data? or is there some other way to address this problem?
i realize this is a somewhat convoluted set-up, but i want to find a way to reconcile the statefulness of gui programming and make it appear to be as pure as possible.