Exit in Lisp

Here’s an idiomatic Lisp example demonstrating the concept of exiting a program:

(defun main ()
  ;; This will not be executed due to the exit
  (unwind-protect
       (progn
         (format t "Exiting the program~%")
         (sb-ext:exit :code 3))
    (format t "This cleanup code won't run!~%")))

;; Run the main function
(main)

This Lisp program demonstrates how to exit a program with a specific status code. Let’s break it down:

  1. We define a main function to encapsulate our program logic.

  2. Inside main, we use unwind-protect, which is similar to try-finally in other languages. It ensures that cleanup code is executed even if an unwind (like an exit) occurs.

  3. The progn form groups multiple expressions together.

  4. We use format to print a message to the console before exiting.

  5. sb-ext:exit is used to exit the program with a specific status code. This is implementation-specific (for SBCL), as Common Lisp doesn’t have a standard way to exit with a status code.

  6. The cleanup code inside unwind-protect won’t be executed due to the immediate exit.

  7. Finally, we call the main function to run our program.

To run this program:

  1. Save the code in a file, e.g., exit-example.lisp.
  2. Run it using a Common Lisp implementation. For example, with SBCL:
$ sbcl --script exit-example.lisp
Exiting the program

To check the exit status in a shell:

$ sbcl --script exit-example.lisp
Exiting the program
$ echo $?
3

Note that the cleanup message “This cleanup code won’t run!” is never printed due to the immediate exit.

This example demonstrates how to exit a Lisp program with a specific status code, which is useful for indicating success or failure to the calling process. It also shows that cleanup code in unwind-protect is not executed when using an exit function, which is an important consideration when designing robust Lisp programs.