Directories in Clojure

Here’s the translation of the Go code to Clojure, along with explanations in Markdown format suitable for Hugo:

Clojure provides several useful functions for working with directories in the file system.

(ns directories
  (:require [clojure.java.io :as io])
  (:import (java.io File)
           (java.nio.file Files Paths)))

(defn check [e]
  (when e
    (throw (Exception. e))))

(defn create-empty-file [name]
  (spit name ""))

(defn main []
  ; Create a new sub-directory in the current working directory.
  (.mkdir (io/file "subdir"))

  ; When creating temporary directories, it's good practice to delete them
  ; when done. In Clojure, we can use `try` with `finally` for cleanup.
  (try
    ; Helper function to create a new empty file.
    (create-empty-file "subdir/file1")

    ; We can create a hierarchy of directories, including parents.
    ; This is similar to the command-line `mkdir -p`.
    (.mkdirs (io/file "subdir/parent/child"))

    (create-empty-file "subdir/parent/file2")
    (create-empty-file "subdir/parent/file3")
    (create-empty-file "subdir/parent/child/file4")

    ; `file-seq` lists directory contents recursively.
    (println "Listing subdir/parent")
    (doseq [file (file-seq (io/file "subdir/parent"))]
      (println " " (.getName file) (.isDirectory file)))

    ; `chdir` in Clojure is done by setting the user.dir system property
    (System/setProperty "user.dir" "subdir/parent/child")

    ; Now we'll see the contents of `subdir/parent/child`
    ; when listing the current directory.
    (println "Listing current directory")
    (doseq [file (file-seq (io/file "."))]
      (println " " (.getName file) (.isDirectory file)))

    ; Change back to where we started.
    (System/setProperty "user.dir" "../../..")

    ; We can also visit a directory recursively, including all its sub-directories.
    (println "Visiting subdir")
    (doseq [file (file-seq (io/file "subdir"))]
      (println " " (.getPath file) (.isDirectory file)))

    (finally
      ; Clean up: delete the subdirectory and all its contents
      (doseq [file (reverse (file-seq (io/file "subdir")))]
        (.delete file)))))

(main)

To run the program, save it as directories.clj and use:

$ clj directories.clj
Listing subdir/parent
  parent true
  child true
  file2 false
  file3 false
  file4 false
Listing current directory
  . true
  file4 false
Visiting subdir
  subdir true
  subdir/file1 false
  subdir/parent true
  subdir/parent/child true
  subdir/parent/child/file4 false
  subdir/parent/file2 false
  subdir/parent/file3 false

This Clojure code demonstrates working with directories, including creating directories, listing contents, changing the current working directory, and walking directory trees. Note that Clojure, being a JVM language, uses Java’s file I/O capabilities under the hood.

The file-seq function is used to recursively list directory contents, which is similar to filepath.WalkDir in the original example. The try/finally block is used to ensure cleanup of the temporary directory, mimicking the defer functionality in the original code.

Remember that in a real-world scenario, you might want to add more error handling and use more idiomatic Clojure constructs for better performance and readability.