(
Lisp people, mainly:)
(unwind-protect
BODYFORM
UNWINDFORMS...)
computes the value of
BODYFORM, executes the
UNWINDFORMS, and returns the value of
BODYFORM. If the computation of
BODYFORM exits "
nonlocally" (e.g. by
throwing) then there
is no
return value of
BODYFORM, but
UNWINDFORMS get executed anyway.
unwind-protect is useful for controlling resources. For instance, it's the place to ensure open files are closed after use. A prog1 form (Scheme's begin) does not work for this when a nonlocal exit occurs. In this respect, unwind-protect is similar to the practice of freeing resources in C++ object destructors -- the destructor gets called during throw() too. So unwind-protect is the procedural counterpart of "resource acquisition is initialization".
If the same invocation of BODYFORM can enter exit multiple times, it's not clear how UNWINDFORMS should be executed, or even how many times! So languages with call/cc (like Scheme) usually don't implement unwind-protect, or do not implement it in a particularly consistent and orthogonal fashion.