Command-Line Applications and Scripting

Startup time: SBCL starts in tens of milliseconds, but loading many libraries is slower. Build an executable or a custom core for fast CLI tools.

;;;; wc.lisp: a word counter CLI using clingon
(ql:quickload '("clingon" "str") :silent t)

(defun count-words-in-file (path)
  (length (str:words (uiop:read-file-string path))))

(defun top-level-handler (cmd)
  (let ((files (clingon:command-arguments cmd))
        (verbose (clingon:getopt cmd :verbose)))
    (dolist (f files)
      (format t "~a~@[ (~a)~]: ~d~%" f (and verbose "words") (count-words-in-file f)))))

(defun make-cli ()
  (clingon:make-command
   :name "wc-lisp"
   :description "Count words in files"
   :usage "[options] FILE..."
   :options (list (clingon:make-option :flag :description "verbose output"
                                             :short-name #\v :long-name "verbose" :key :verbose))
   :handler #'top-level-handler))

(defun main ()
  (clingon:run (make-cli)))
# Scripting with sbcl --script (shebang)
#!/usr/bin/env -S sbcl --script
(format t "Args: ~a~%" (rest sb-ext:*posix-argv*))

# Roswell scripts
ros init myscript          # creates myscript.ros with a main function
ros build myscript.ros     # build an executable