3.2 Explanation

Let’s examine this program step-by-step now.

First, we put ourselves in the Common Lisp user package, and load Clon’s main ASDF system, called ‘net.didierverna.clon’. Next, we use the Clon package, also named ‘net.didierverna.clon’.

(in-package :cl-user)

;; This is the ASDF way, but use Quicklisp's ql:quickload if you prefer.
(require "asdf")
(asdf:load-system :net.didierverna.clon)
(use-package :net.didierverna.clon)

In fact, using the Clon package directly is done here for simplicity, but is not recommended. In case you find the package name too long to prefix every symbol with, Clon provides a utility function that allows you to add (and use) a shorter nickname instead (the demonstration programs in the distribution show how to use it):

Function: nickname-package &optional NICKNAME

Add NICKNAME (:clon by default) to the :NET.DIDIERVERNA.CLON package.

The next thing you want to do is to create a set of options, groups or texts that your application will recognize and/or display in its help string. The structure of your command-line is known to Clon as the synopsis. In order to create it, use the macro defsynopsis.

(defsynopsis (:postfix "FILES...")
  (text :contents "A very short program.")
  (group (:header "Immediate exit options:")
    (flag :short-name "h" :long-name "help"
          :description "Print this help and exit.")
    (flag :short-name "v" :long-name "version"
          :description "Print version number and exit.")))

Note that the synopsis has a double role: it not only serves to define the options recognized by your application, but also the order in which every element appears in the help string. In that particular example, we define a line of text and a group with a header and two flags.

Now, we are going to define a function main for our standalone application. The first thing that we need to do is create a context. A context is an object that Clon uses to store various things, including some state related to the parsing of the command-line. You create a context with the function make-context.

(defun main ()
  "Entry point for our standalone application."
  (make-context)

At that point, Clon is ready to retrieve the options you want from the command-line. Let’s first see if the user has called the option -h, and give him the help string. Option retrieval is done with the function getopt, and automatic help string output with the function help. Note that what we do here is not process the command-line in sequence, but look directly for a specific option by name (this retrieval method is said to be explicit).

  (when (getopt :short-name "h")
    (help)
    (uiop:quit))

UIOP’s quit function is a portable wrapper around an implementation-dependent way of saying goodbye. It takes an exit status code as optional argument.

And now, we are going to retrieve the other options and simply print them. This time however, we process the command-line sequentially (so this retrieval method is said to be sequential). This is done with the do-cmdline-options macro. We also close the main function.

  (do-cmdline-options (option name value source)
    (print (list option name value source)))
  (terpri)
  (uiop:quit))

Finally, time to save the Lisp image.

(dump "quickstart" main)

The first argument to dump is the name of the executable to produce, and the second argument is the name of the function to call automatically at startup. In fact, dump also accepts a &rest argument that just be passed on to the underlying (implementation-specific) dumping facility.

In order to get a standalone executable from this program, all you need to do now is to type ‘sbcl --script quickstart.lisp’. Note that the actual way of dumping executables is compiler-dependent. For more information on the proper way to do it and on the compilers currently supported, see Dumping Executables. Note also that it is possible to use Clon without actually dumping a standalone executable (see Delivering Scripts) at all.