💾 Archived View for gemlog.blue › users › verachell › 1644768654.gmi captured on 2024-03-21 at 17:18:41. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2022-03-01)

-=-=-=-=-=-=-

Correct usage of unwind-protect and with-open-file in Lisp

Note: This post is a Gemini space version of my post originally published on September 9, 2018

https version of this post

Learning to use unwind-protect in Lisp typically crops up very early on when you're first learning the language. In fact, anything to do with I/O is going to be something you'll need to know early on.

Yet unfortunately, I find that unwind-protect is not explained sufficiently well for a beginner to understand not just HOW to use it correctly, but WHY and WHEN. Grappling with this myself, I found that hands-down the best explanation came from this YouTube video from Baggers:

https - Little bits of Lisp - unwind-protect by Baggers on YouTube

Luckily, in the case of file handlers, LISP already assumes you'll want to open a file with unwind-protect, so it provides the with-open-file macro for this exact purpose. It closes the file handler for you with a built-in unwind-protect. This is an advantage over manually opening and closing your file handlers, because if your program opens the file but never gets to the part with the close command (for example due to a run-time error in between those stages), the built-in unwind-protect makes sure the close command still gets executed.

And yes, you COULD certainly open files with an explicit unwind-protect and do the closing during the clean-up part of the unwind-protect, but such constant repetition every time you open a file is not the LISP way! Using with-open-file lets you do exactly the same thing with less code.

When should you use unwind-protect, and when should you use the applicable with-whatever macro?

For the majority of your file opening and closing, with-open-file is what you'd need.

Using unwind-protect is critical when either:

a) there is no corresponding macro for your task that has built-in unwind-protect

or

b) you want to ensure an additional task (or multiple extra tasks) gets executed also besides closing the file handler, during the clean-up phase. In that case, you will need unwind-protect to achieve that.

The key to understanding the reasoning behind this though, is to go through the video shown above by Baggers. It's hands-down by far the best explanation I've found on correct usage of unwind-protect in LISP. Once you understand the video (especially the bits in the last few minutes) you'll understand how, why, and when you'll want to use unwind-protect and when you might instead want to use a corresponding macro like with-open-file, if one is available for your desired purpose.