Running a Common Lisp function from a Terminal command prompt

common-lisp, lisp, sbcl

Solution

The SBCL manual describes three useful options

3.3.1 Runtime Options

`--noinform` Suppress the printing of any banner or other informational message at startup. This makes it easier to write Lisp programs which work cleanly in Unix pipelines. See also the `--noprint` and `--disable-debugger` options.

3.3.2 Toplevel Options

`--eval command` After executing any initialization file, but before starting the read-eval-print loop on standard input, read and evaluate the command given. More than one `--eval` option can be used, and all will be read and executed, in the order they appear on the command line.

`--load filename` This is equivalent to `--eval '(load "filename")'`. The special syntax is intended to reduce quoting headaches when invoking SBCL from shell scripts.

Given a file `test.lisp` with contents

(defun hello-world ()
  (print 'hello-world)
  (terpri))

we can do this with SBCL:

$ sbcl --noinform --load test.lisp --eval '(progn (hello-world) (sb-ext:quit))'

HELLO-WORLD 

The `(progn ... (sb-ext:quit))` makes sure that the program ends after executing `(hello-world)`. Otherwise you get dropped into the SBCL prompt. Since code is compiled automatically in SBCL, the function that you're running is already compiled by the time `(hello-world)` is run. If you've compiled the file in advance, you can pass the compiled file to `--load`. E.g.,

$ sbcl --noinform --load test.fasl --eval '(hello-world)'

HELLO-WORLD 

In fact,given the equivalence of `--load` to `--eval (load "filename")`, you can just use the base of the file name, and if there's a compiled version, then SBCL should load that, and if there's not, then SBCL will load the source file and you'll get compiled code that way. E.g., in the following, we use just `--load test`:

$ sbcl --noinform --load test --eval '(hello-world)'

HELLO-WORLD 

Problem

I'm having some difficulty finding an answer to this, so maybe it isn't possible. I'd like the flexibility of being able to load/compile a lisp file from a command line, i.e. not inside emacs, and then also run one of the lisp functions in that file also from the command line. This is no doubt implementation specific feature, so any pointers on an implementation that offers this (or perhaps it is fairly standard, I don't know). I'm using SBCL and like it, so it would be great if that could do this. Also I'm using Mac OSX and Terminal.

Original source