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
cleanup
function that simulates a cleanup operation. In a real-world scenario, this might involve closing file handles or database connections.The
exit-program
function is our custom exit function. It prints the exit status and then callsSystem/exit
with the given status code. This is equivalent toos.Exit
in Go.In the
-main
function, we useaddShutdownHook
to register our cleanup function. This is similar to usingdefer
in Go, but it’s important to note that shutdown hooks are not guaranteed to run when usingSystem/exit
.We then call
exit-program
with 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: 3
To check the exit status in a shell:
$ clj exit_example.clj
Starting the program
Exiting with status: 3
$ echo $?
3
Note 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.