December 16, 2020

Learning Clojure - Implementing true and false

As I wrote previously, I am learning the Clojure programming language as one of my personal Learning Projects. Naturally I started with hello world because there are a ton of examples of hello world available and just being able to get it working proves that you're gotten your development environment setup correctly.

Now that I have moved past hello world, I am ready for the first programs that I will have to write myself. No copy and paste of a complete working version, or because I am using lein I get a copy supplied everytime I start a new project. So, it is time to write the simplest programs that it is possible to write in almost every programming language I've ever used, the equivalents of the Unix utilities true and false. These are so simple to write because they do nothing except exit and pass an integer value back to the operating system. In the Unix world, where these come from, the convention is that a zero indicates success and a non-zero indicates failure, with again the convention being that the false utility returns a one. (Naturally, other utilities are free to return any non-zero value they wish, but `false is going to give you a one.)

A challenge when setting up the projects was finding that Clojure does not allow language keywords as filenames, so true.clj and false.clj were not options. Necessity brings out invention, so I named them cljtrue.clj and cljfalse.clj. Not the most exciting names, but they work. (That's actually pretty good considering that I'm a graduate of the Jocko school of naming things!)

Now, let's take a look at the code:

(ns cljtrue.core
  (:gen-class))

(defn -main
  "Equivalent of the Unix CLI utility `true`. Returns a zero (Unix truth) as it's exit value."
  [& args]
  (System/exit 0))
(ns cljfalse.core
  (:gen-class))

(defn -main
  "Equivalent of the Unix CLI utility `false`. Returns a one (Unix treats any non-zero value as false) as it's exit value."
  [& args]
  (System/exit 1))

I'm not gonna lie here. I took the lein provided hello world, updated the function description and started searching online for ways to get Clojure to return an exit value to the operating system. A few searches later and I am reminded that Clojure is happy to use parts of it's Java heritage wherever it can and that exiting a program with a defined exit code is one of those things. In Java we would use System.exit(), so in Clojure we write (System/exit 0) for returning a true and (System/exit 1) for returning a false.

I've got to admit that that was easier than I had feared. Some of the Java interoperability in Clojure is very straightforward and just works. I greatly appreciate that. Especially when it's something that Clojure leaves for the Java platform to take care of for it.

Tags: Clojure