Releasing Sbcl-Script 1.0.1 (first release)

I am hereby releasing the first version (1.0.1) of sbcl-script. The source is available on Gitlab and on Github. The primary site is, for the moment, Gitlab.

Sbcl-Script is not a big thing, just a tiny script written in Steel Bank Common Lisp which can be used in a hash-bang line to run a common lisp script.

#!/usr/bin/env sbcl-script

(do-something)

The same can in principle be achieved with sbcl --script, but sbcl --script does not read any init files, whereas sbcl-script does read system and user init files.

For more details read on below.

Motivation

Small utilities written in Lisp can be most easily deployed by using scripts instead of dumping (usually large) system images. The purpose of the script is to load some systems and then invoke a function (an entry point) in one of those systems.

#!/usr/bin/sbcl --script
(require 'asdf)
(let ((*standard-output* *error-output*))
  (asdf:load-system "your.domain.your-system"))
(your-package:your-main-function)

This works well for deployment, when the script is installed in for example /usr/bin and the system in a distribution specific directory under /usr/share, for example in Arch Linux under /usr/share/common-lisp/source.

But while developing the system, one would like to run the script locally, against e.g. the system located or linked in local-projects of a per user installation of Quicklisp. Such a local install of Quicklisp (or ASDF directories in the user's home) is usually set up in ~/.sbclrc, but sbcl --script never loads the user initialization file, so don't know about those and only can load systems installed in the global directory under /usr/share.

Python, in comparison, is much more friendly there, in that it allows the user to easily set up an individual virtual environment, in which all development can be done.

Steel Bank Common Lisp also allows to set up an individual environment with a bit more work (with Quicklisp and possibly using asdf:initialize-source-registry in .sbclrc to define further locations for ASDF systems), but the use of sbcl --script then jumps out of this virtual environment, making the scripts unusable when developing.

Sbcl-Script comes to the rescue fix this problem. It works mostly like sbcl --script but also process system wide and user specific initialization files for SBCL (/etc/sbclrc and ~/.sbclrc).

So we would have (instead of the fragment above):

#!/usr/bin/env -S sbcl-script
(require 'asdf)
(let ((*standard-output* *error-output*))
  (asdf:load-system "your.domain.your-system"))
(your-package:your-main-function)

but during installation of our package replace the hash-bang line with

#!/usr/bin/sbcl --script

so that the installed script runs against the system wide installed ASDF systems, not against whatever the user has installed at that time.

Using Sbcl-Script

As shown above, write scripts as follows:

#!/usr/bin/env -S sbcl-script
(require 'asdf)
(let ((*standard-output* *error-output*))
  (asdf:load-system "your.domain.your-system"))
(your-package:your-main-function)

Then during installation (e.g. by make install) replace the hash-bang line:

#!/usr/bin/sbcl --script
(require 'asdf)
(let ((*standard-output* *error-output*))
  (asdf:load-system "your.domain.your-system"))
(your-package:your-main-function)

Further reading

A blog post and PoC code (Makefile, PKGBUILD) on how to deploy small Lisp applications as scripts is forthcoming on Glitzersachen. It will be linked here.

Updates

  • 2023-04-09 — PoC code is now over there in my public proof of concept repository.

Comments

Due to legal pitfalls in Europe there is no comment section in this blog at the moment (sorry), but you can discuss this article or comment on its content ➡ here on Mastodon.