Exit in Clojure
Here’s an idiomatic Clojure example demonstrating the concept of exiting a program:
(ns exit-example
(:require [clojure.java.shell :as shell]))
;; This function will not be called due to early exit
(defn cleanup []
(println "Cleanup function called!"))
(defn exit-program [status]
(println "Exiting with status:" status)
;; The following line will prevent the cleanup function from being called
(System/exit status))
(defn -main []
;; Register cleanup function to be called on normal exit
(.addShutdownHook (Runtime/getRuntime) (Thread. cleanup))
(println "Starting the program")
;; Exit with status 3
(exit-program 3))
;; Run the program
(-main)This Clojure program demonstrates how to exit a program with a specific status code. Let’s break down the key components:
We define a
cleanupfunction that simulates a cleanup operation. In a real-world scenario, this might involve closing file handles or database connections.The
exit-programfunction is our custom exit function. It prints the exit status and then callsSystem/exitwith the given status code. This is equivalent toos.Exitin Go.In the
-mainfunction, we useaddShutdownHookto register our cleanup function. This is similar to usingdeferin Go, but it’s important to note that shutdown hooks are not guaranteed to run when usingSystem/exit.We then call
exit-programwith a status of 3, which will immediately terminate the program.
To run this program:
- Save the code in a file named
exit_example.clj. - Run it using the Clojure command-line tool:
$ clj exit_example.clj
Starting the program
Exiting with status: 3To check the exit status in a shell:
$ clj exit_example.clj
Starting the program
Exiting with status: 3
$ echo $?
3Note that the cleanup function is not called due to the use of System/exit. This behavior is similar to Go’s os.Exit, which also doesn’t run deferred functions.
In Clojure, it’s generally preferred to let the program exit normally rather than using System/exit. This allows for proper resource cleanup and is considered more idiomatic. However, System/exit is available when you need to forcibly terminate the program with a specific exit code.
Remember that in Clojure, like in Go, the return value of the -main function is not used to determine the exit status. To set a non-zero exit status, you must use System/exit explicitly.