Go + Clojure = Glojure

Which means I'm migrating from Babashka to Glojure

20 September 2025 golang clojure

At a previous job I had the opportunity to learn Clojure, but most of my career has centered on Go.

I have a collection of little scripts that I have written in Clojure, but I've used Babashka to execute them because I got tired of the JVM's slow startup time.

The thing that has always bothered me about Clojure is that I'm not super familiar with the Java Platform's standard library, which turns out to be more important than you'd think. Even when using Babashka, which is Clojure interpreter totally separate from the JVM, it includes a bunch of Java classes.

Well, I just found Glojure, a new-ish Clojure interpreter on the Go platform. Being written in Go means it has access to many packages in the Go standard library, which I am much more familiar with.

I have several scripts that simply print items in a checklist as I hit <enter> (in the spirit of Dan Slimmon's 'Do Nothing Script' concept).

Here's an example of what it looked like before:

#!/usr/bin/env bb

(def steps
  ["Step 1"
   "Step 2"
   "Step 3"])

(doseq [n (range (count steps))]
  (printf "%d. %s" (inc n) (nth steps n))
  (flush)
  (read-line))

Notice the shebang (#!/usr/bin/env bb), which tells my OS to use bb (the Babashka command) to execute the script.

Also notice the call to (flush). I guess babashka is buffering, even to stdout, and I've never liked that.

Here's the output of the script (after hitting enter 3 times):

$ ./example.clj
1. Step 1
2. Step 2
3. Step 3

Here's the same script migrated to Glojure:

#!/usr/bin/env glj

(def steps
  ["Step 1"
   "Step 2"
   "Step 3"])

(doseq [n (range (count steps))]
  (fmt.Printf "%d. %s" (inc n) (nth steps n))
  (fmt.Scanln))

Note the modified shebang (ending in glj). Now I'm just using good old fmt.Printf and fmt.Scanln to print and wait for <enter>.

Here's a more complicated example that formatted the current date with the format 20 September 2025 Saturday, which took a surprising amount of fiddling with the Java time APIs:

(import 'java.time.format.DateTimeFormatter
        'java.time.LocalDateTime)

(def date (LocalDateTime/now))
(def weekday (clojure.string/capitalize (.getDayOfWeek date)))
(def formatter (DateTimeFormatter/ofPattern "d MMMM yyyy"))
(def pretty-date (str (.format date formatter) " " weekday))

(Maybe there's a better way with Java? Not sure.)

Here's the same code in Glojure, using Go's "time" package:

(def pretty-date (.Format (time.Now) "2 January 2006 Monday"))

While I've critized Go's use of a static reference time to specify formatting output, the whole time API is quite convenient to use.

The only real capability available in babashka that I've missed Glojure is the pprint package, but the following function is helping me get by for now:

(defn pprint [v]
  (doseq [x v]
    (fmt.Println x)))