Directories in Racket

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

Our first program will demonstrate working with directories in Racket. Here’s the full source code:

#lang racket

(require racket/file)

;; Helper function to create an empty file
(define (create-empty-file name)
  (with-output-to-file name
    (lambda () (void))
    #:exists 'replace))

;; Main function
(define (main)
  ;; Create a new sub-directory in the current working directory
  (make-directory "subdir")

  ;; When creating temporary directories, it's good practice to delete them afterwards
  ;; We'll use dynamic-wind to ensure cleanup happens
  (dynamic-wind
    (lambda () (void))  ; setup (none needed here)
    (lambda ()
      ;; Create some files and directories
      (create-empty-file "subdir/file1")
      (make-directory* "subdir/parent/child")
      (create-empty-file "subdir/parent/file2")
      (create-empty-file "subdir/parent/file3")
      (create-empty-file "subdir/parent/child/file4")

      ;; List directory contents
      (printf "Listing subdir/parent\n")
      (for ([entry (directory-list "subdir/parent")])
        (printf " ~a ~a\n" entry (directory-exists? (build-path "subdir/parent" entry))))

      ;; Change current working directory
      (current-directory "subdir/parent/child")

      ;; List contents of current directory
      (printf "Listing subdir/parent/child\n")
      (for ([entry (directory-list)])
        (printf " ~a ~a\n" entry (directory-exists? entry)))

      ;; Change back to original directory
      (current-directory "../../..")

      ;; Recursively visit the directory
      (printf "Visiting subdir\n")
      (for ([path (in-directory "subdir")])
        (printf " ~a ~a\n" path (directory-exists? path))))
    (lambda ()
      ;; Cleanup: remove the created directory and all its contents
      (delete-directory/files "subdir"))))

;; Run the main function
(main)

Let’s break down the key parts of this program:

  1. We define a helper function create-empty-file to create empty files.

  2. In the main function, we use make-directory to create a new subdirectory.

  3. We use dynamic-wind to ensure cleanup happens even if an error occurs.

  4. make-directory* is used to create a hierarchy of directories (similar to mkdir -p in shell).

  5. We use directory-list to get the contents of a directory, and directory-exists? to check if an entry is a directory.

  6. current-directory is used to change the current working directory (similar to cd in shell).

  7. in-directory is used for recursively visiting a directory and its subdirectories.

  8. Finally, we use delete-directory/files to remove the created directory and all its contents.

To run this program, save it as directories.rkt and use the racket command:

$ racket directories.rkt
Listing subdir/parent
 child #t
 file2 #f
 file3 #f
Listing subdir/parent/child
 file4 #f
Visiting subdir
 /path/to/subdir #t
 /path/to/subdir/file1 #f
 /path/to/subdir/parent #t
 /path/to/subdir/parent/child #t
 /path/to/subdir/parent/child/file4 #f
 /path/to/subdir/parent/file2 #f
 /path/to/subdir/parent/file3 #f

This program demonstrates various operations on directories in Racket, including creating, listing, and recursively visiting directories and files.