Resource management in the MIT Lisp OS ca. 1980, approximate example.
One would define a resource of arrays, where arrays can be allocated and deallocated. They will be managed via a pool.
(defresource 2d-array (rows columns)
:constructor (make-array (list rows columns)))
Now user code would use the USING-RESOURCE macro, where it spans a dynamic scope. Entering the scope allocates the resource. Inside the scope the resource is allocated. Leaving the scope will automatically deallocate the resource and put it back into the pool. A deinitializer may free memory as needed. (using-resource (my-array 2d-array 100 100) ; get me a 100x100 array from a pool
(setf (aref my-array 42 42) 'the-answer) ; setting the array
(print (aref my-array 42 42))) ; reading the array
To make sure that the resource gets deallocated, the above macro form will expand to something using UNWIND-PROTECT: ...
(unwind-protect
(progn ; protected form
(setf my-array (allocate-resource '2d-array 100 100)) ; allocate the array
(setf (aref my-array 42 42) 'the-answer) ; setting the array
(print (aref my-array 42 42))) ; reading the array
(when my-array ; exit form
(deallocate-resource '2d-array my-array))) ; deallocate the array
...
This is an example of manual memory management using a pool of resources, where the DEALLOCATE is done always via UNWIND-PROTECT.Thus the user will not explicitly use UNWIND-PROTECT, but some macros which use it in their expansion...