Command Line Flags in Racket

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

Command-line flags are a common way to specify options for command-line programs. For example, in wc -l the -l is a command-line flag.

Racket provides a command-line function for parsing command-line arguments. We’ll use this function to implement our example command-line program.

#lang racket

(require racket/cmdline)

(define word (make-parameter "foo"))
(define numb (make-parameter 42))
(define fork (make-parameter #f))
(define svar (make-parameter "bar"))

(define (main)
  (command-line
   #:program "command-line-flags"
   #:usage-help
   "Example program demonstrating command-line flag parsing"
   
   #:once-each
   [("-w" "--word") w
    "a string"
    (word w)]
   [("-n" "--numb") n
    "an integer"
    (numb (string->number n))]
   [("-f" "--fork")
    "a boolean flag"
    (fork #t)]
   [("-s" "--svar") s
    "a string variable"
    (svar s)]
   
   #:args (arg . rest)
   (begin
     (printf "word: ~a\n" (word))
     (printf "numb: ~a\n" (numb))
     (printf "fork: ~a\n" (fork))
     (printf "svar: ~a\n" (svar))
     (printf "tail: ~a\n" (cons arg rest)))))

(main)

In this Racket program:

  1. We use make-parameter to create mutable parameters for our flags. These are similar to the pointers used in the original example.

  2. The command-line function is used to define and parse the command-line options. It’s more declarative than the Go approach, but serves a similar purpose.

  3. We define options using #:once-each, which specifies that each option can appear at most once. Each option is defined with a short form, a long form, a description, and a function to handle the option’s value.

  4. The #:args clause handles any additional arguments after the flags.

  5. Finally, we print out all the parsed options and any trailing arguments.

To experiment with this program, save it as command-line-flags.rkt and run it using racket:

$ racket command-line-flags.rkt -word=opt -numb=7 -fork -svar=flag
word: opt
numb: 7
fork: #t
svar: flag
tail: ()

If you omit flags, they keep their default values:

$ racket command-line-flags.rkt -word=opt
word: opt
numb: 42
fork: #f
svar: bar
tail: ()

You can provide additional arguments after the flags:

$ racket command-line-flags.rkt -word=opt a1 a2 a3
word: opt
numb: 42
fork: #f
svar: bar
tail: (a1 a2 a3)

To get help text for the program, use the -h or --help flag:

$ racket command-line-flags.rkt -h
command-line-flags [ <option> ... ]
 where <option> is one of
  -w <w>, --word <w> : a string
  -n <n>, --numb <n> : an integer
  -f, --fork : a boolean flag
  -s <s>, --svar <s> : a string variable
  --help, -h : Show this help
  -- : Do not treat any remaining argument as a switch (at this level)
 Multiple single-letter switches can be combined after one `-'; for
  example: `-h-' is the same as `-h --'

This Racket implementation provides similar functionality to the original example, using Racket’s built-in command-line parsing capabilities.