Command Line Subcommands in Scheme
Here’s the translation of the Go code to Scheme, formatted in Markdown suitable for Hugo:
Our first example demonstrates how to implement command-line subcommands in Scheme. This is similar to how tools like git have multiple subcommands, each with its own set of flags.
(import (scheme base)
        (scheme process-context)
        (scheme write))
(define (parse-args args)
  (let ((subcommand (if (null? args) "" (car args)))
        (rest-args (if (null? args) '() (cdr args))))
    (case subcommand
      (("foo")
       (let-values (((enable name rest) (parse-foo-args rest-args)))
         (display "subcommand 'foo'\n")
         (display "  enable: ") (display enable) (newline)
         (display "  name: ") (display name) (newline)
         (display "  tail: ") (display rest) (newline)))
      (("bar")
       (let-values (((level rest) (parse-bar-args rest-args)))
         (display "subcommand 'bar'\n")
         (display "  level: ") (display level) (newline)
         (display "  tail: ") (display rest) (newline)))
      (else
       (display "expected 'foo' or 'bar' subcommands\n")
       (exit 1)))))
(define (parse-foo-args args)
  (let loop ((args args) (enable #f) (name "") (rest '()))
    (if (null? args)
        (values enable name rest)
        (let ((arg (car args)))
          (cond
           ((string=? arg "--enable") (loop (cdr args) #t name rest))
           ((string-prefix? arg "--name=")
            (loop (cdr args) enable (substring arg 7) rest))
           (else (loop (cdr args) enable name (cons arg rest))))))))
(define (parse-bar-args args)
  (let loop ((args args) (level 0) (rest '()))
    (if (null? args)
        (values level rest)
        (let ((arg (car args)))
          (cond
           ((string-prefix? arg "--level=")
            (loop (cdr args) (string->number (substring arg 8)) rest))
           (else (loop (cdr args) level (cons arg rest))))))))
(parse-args (cdr (command-line)))This Scheme program implements a basic command-line subcommand structure. Here’s how it works:
We define a main
parse-argsfunction that handles the subcommands.For each subcommand (
fooandbar), we define separate parsing functions (parse-foo-argsandparse-bar-args).The
parse-argsfunction checks the first argument to determine which subcommand to run.Each subcommand parser function processes its specific flags and arguments.
To run this program, save it to a file (e.g., subcommands.scm) and use your Scheme interpreter. Here are some example invocations:
$ scheme --script subcommands.scm foo --enable --name=joe a1 a2
subcommand 'foo'
  enable: #t
  name: joe
  tail: (a2 a1)
$ scheme --script subcommands.scm bar --level=8 a1
subcommand 'bar'
  level: 8
  tail: (a1)
$ scheme --script subcommands.scm baz
expected 'foo' or 'bar' subcommandsNote that Scheme doesn’t have built-in command-line argument parsing libraries like Go’s flag package, so we’ve implemented a simple parsing mechanism. In a real-world scenario, you might want to use a more robust command-line parsing library for Scheme if available.