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-args
function that handles the subcommands.For each subcommand (
foo
andbar
), we define separate parsing functions (parse-foo-args
andparse-bar-args
).The
parse-args
function 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' subcommands
Note 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.