3 ms·
It shouldn't be very hard to create a basic ownership system. Here is a version I just wrote, which works by defining a new version of "defun" that uses dynamic
by malisper 12y ago
It shouldn't be very hard to create a basic ownership system. Here is a version I just wrote, which works by defining a new version of "defun" that uses dynamic variables to keep track of ownership:
(defvar *transferring* '() "Objects which are going to be transferred from one owner to another.")
(defvar *resources* '() "The resources which need to be freed when the current procedure is done.")
(defmacro new-defun (name args &body body)
"Define a procedure which will have ownership over the resources it creates using any of the 'new' procedures.
`(defun ,name ,args
(let ((*resources* *transferring*))
(setf *transferring* '())
(unwind-protect (progn ,@body)
(mapcar #'free *resources*)
(mapcar #'free *transferred*))))) ; These are resources which were supposed to be transferred by weren't due to an error.
(defun transfer (resource)
"Transfer ownership of a resource from the current one to the next procedure called which can accept ownership."
(push resource *transferring*)
(setf *resources* (remove resource *resources*))
resource)
(defun new-open (&rest args)
"Open a file whose owner is the first procedure up the stack which can accept ownership."
(let ((file (apply #'open args)))
(push file *resources*)
file))
All that is needed now is a method "free" which will free any given resource. With this, any resource allocated with a "new" procedure (the only one I wrote was "new-open") will by put under ownership of the last procedure on the stack which was defined with "new-defun". Transfer between owners can take place by using "transfer". The best part is that more facilities are easy to build on top of this. The "drop" procedure would be trivial to add. The only problem I can see here is that there may be some issues if "free" throws an error, since "unwind-protect" doesn't protect the cleanup-forms. This should be fixable by just wrapping every call to "free" with "ignore-errors".