Directories in Lisp
Here’s the translation of the Go code to Lisp, formatted in Markdown for Hugo:
Our first program demonstrates working with directories in the file system. Here’s the full source code:
(defpackage :directories-example
(:use :cl :uiop))
(in-package :directories-example)
(defun check (condition)
(unless condition
(error "An error occurred")))
(defun create-empty-file (name)
(with-open-file (stream name :direction :output :if-exists :supersede)
(write-string "" stream)))
(defun main ()
;; Create a new sub-directory in the current working directory.
(ensure-directories-exist "subdir/")
;; When creating temporary directories, it's good practice to clean them up afterwards.
;; Here we use UIOP:DELETE-DIRECTORY-TREE which is similar to `rm -rf`.
(unwind-protect
(progn
(create-empty-file "subdir/file1")
;; We can create a hierarchy of directories, including parents.
;; This is similar to the command-line `mkdir -p`.
(ensure-directories-exist "subdir/parent/child/")
(create-empty-file "subdir/parent/file2")
(create-empty-file "subdir/parent/file3")
(create-empty-file "subdir/parent/child/file4")
;; LIST-DIRECTORY lists directory contents.
(format t "Listing subdir/parent~%")
(dolist (entry (uiop:directory-files "subdir/parent/"))
(format t " ~A ~A~%"
(file-namestring entry)
(uiop:directory-pathname-p entry)))
;; CHDIR lets us change the current working directory.
(uiop:chdir "subdir/parent/child")
;; Now we'll see the contents of `subdir/parent/child` when listing the current directory.
(format t "Listing subdir/parent/child~%")
(dolist (entry (uiop:directory-files "./"))
(format t " ~A ~A~%"
(file-namestring entry)
(uiop:directory-pathname-p entry)))
;; Change back to where we started.
(uiop:chdir "../../..")
;; We can also visit a directory recursively, including all its sub-directories.
(format t "Visiting subdir~%")
(walk-directory "subdir"))
;; Clean up the directory we created
(uiop:delete-directory-tree "subdir/" :validate t :if-does-not-exist :ignore)))
(defun walk-directory (directory)
(uiop:collect-sub-directories
directory
(lambda (dir)
(format t " ~A ~A~%" dir (uiop:directory-pathname-p dir))
(dolist (file (uiop:directory-files dir))
(format t " ~A ~A~%" file (uiop:directory-pathname-p file))))))
(main)
This Lisp program demonstrates various operations on directories:
We use
ensure-directories-exist
to create directories, which is similar toos.MkdirAll
in Go.uiop:delete-directory-tree
is used for recursive directory deletion, similar toos.RemoveAll
.uiop:directory-files
is used to list directory contents, analogous toos.ReadDir
.uiop:chdir
changes the current working directory, just likeos.Chdir
.We implement a
walk-directory
function that recursively visits all subdirectories and files, similar tofilepath.WalkDir
in Go.The
unwind-protect
macro is used to ensure cleanup of the created directory, similar to Go’sdefer
.
To run this program, save it as directories.lisp
and use your Lisp implementation. For example, with SBCL:
$ sbcl --script directories.lisp
Listing subdir/parent
child T
file2 NIL
file3 NIL
Listing subdir/parent/child
file4 NIL
Visiting subdir
/path/to/subdir/ T
/path/to/subdir/file1 NIL
/path/to/subdir/parent/ T
/path/to/subdir/parent/child/ T
/path/to/subdir/parent/child/file4 NIL
/path/to/subdir/parent/file2 NIL
/path/to/subdir/parent/file3 NIL
Note that the exact output might vary depending on your Lisp implementation and operating system.