File Paths in Scheme

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

The filepath package in Scheme doesn’t have a direct equivalent, but we can implement similar functionality using string manipulation and system-specific path operations. We’ll use the (srfi :13) library for string operations and create our own functions to mimic the behavior of Go’s filepath package.

(import (rnrs)
        (srfi :13))

;; Join function to construct paths
(define (join . parts)
  (string-join (filter (lambda (s) (not (string=? s ""))) parts) "/"))

;; Dir function to get the directory part of a path
(define (dir path)
  (let ((last-slash (string-index-right path #\/)))
    (if last-slash
        (substring path 0 last-slash)
        ".")))

;; Base function to get the last element of a path
(define (base path)
  (let ((last-slash (string-index-right path #\/)))
    (if last-slash
        (substring path (+ last-slash 1))
        path)))

;; IsAbs function to check if a path is absolute
(define (is-abs path)
  (char=? (string-ref path 0) #\/))

;; Ext function to get the file extension
(define (ext filename)
  (let ((dot-index (string-index-right filename #\.)))
    (if dot-index
        (substring filename dot-index)
        "")))

;; Rel function to find a relative path
(define (rel base target)
  (let* ((base-parts (string-split base #\/))
         (target-parts (string-split target #\/))
         (common-prefix-length (let loop ((i 0))
                                 (if (and (< i (length base-parts))
                                          (< i (length target-parts))
                                          (string=? (list-ref base-parts i)
                                                    (list-ref target-parts i)))
                                     (loop (+ i 1))
                                     i)))
         (up-count (- (length base-parts) common-prefix-length))
         (down-parts (list-tail target-parts common-prefix-length)))
    (string-join
     (append (make-list up-count "..")
             down-parts)
     "/")))

(define (main)
  (let ((p (join "dir1" "dir2" "filename")))
    (display "p: ")
    (display p)
    (newline)

    (display (join "dir1//" "filename"))
    (newline)
    (display (join "dir1/../dir1" "filename"))
    (newline)

    (display "Dir(p): ")
    (display (dir p))
    (newline)
    (display "Base(p): ")
    (display (base p))
    (newline)

    (display (is-abs "dir/file"))
    (newline)
    (display (is-abs "/dir/file"))
    (newline)

    (let* ((filename "config.json")
           (extension (ext filename)))
      (display extension)
      (newline)
      (display (string-trim-right filename extension))
      (newline))

    (let ((rel-path (rel "a/b" "a/b/t/file")))
      (display rel-path)
      (newline))

    (let ((rel-path (rel "a/b" "a/c/t/file")))
      (display rel-path)
      (newline))))

(main)

This Scheme code provides similar functionality to the Go example for file path operations. Here’s a breakdown of the main differences and adaptations:

  1. We import (rnrs) for basic Scheme functionality and (srfi :13) for additional string operations.

  2. We define our own join, dir, base, is-abs, ext, and rel functions to mimic the behavior of Go’s filepath package.

  3. The join function uses string-join to concatenate path parts, filtering out empty strings.

  4. The dir and base functions use string manipulation to split paths.

  5. The is-abs function checks if the path starts with a forward slash.

  6. The ext function finds the last dot in the filename and returns the substring from that point.

  7. The rel function is more complex, as it needs to calculate the relative path between two absolute paths.

  8. In the main function, we use display and newline for output instead of fmt.Println.

  9. String operations like TrimSuffix are replaced with string-trim-right.

To run this Scheme program, save it to a file (e.g., file-paths.scm) and execute it using your Scheme interpreter. The output should be similar to the Go example, demonstrating various file path operations in Scheme.