# Steel Bank Common Lisp (2026-08-20)

**URL:** <https://pluralist.net/t/steel-bank-common-lisp-2026-08-20/345>\
**Category:** Code Reading\
**Created:** [August 21, 2026, 5:40am UTC](https://pluralist.net/t/steel-bank-common-lisp-2026-08-20/345 "2026-08-21T05:40:07Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![delyan](https://pluralist.net/user_avatar/pluralist.net/delyan/32/245_2.png) [@delyan](https://pluralist.net/u/delyan)\
**Post date:** [August 21, 2026, 5:40am UTC](https://pluralist.net/t/steel-bank-common-lisp-2026-08-20/345/1 "2026-08-21T05:40:07Z")

</div>

# SBCL: Steel Bank Common Lisp

I’ve been playing with **SBCL** , or **Steel Bank Common Lisp**.

SBCL is one of the main modern implementations of **Common Lisp**. It is both a compiler and runtime, and it compiles Lisp into native machine code.

The name is amusing.

SBCL descends from **CMUCL — Carnegie Mellon University Common Lisp**.

The developers turned _Carnegie Mellon_ into a joke:

- **Carnegie** → Andrew Carnegie → **steel**
- **Mellon** → Mellon family → **banking**
- **Carnegie Mellon** → **Steel Bank**

Hence:

> **Steel Bank Common Lisp**

## The simplest possible program

```lisp
(format t "Hello, world!~%")

```

Save that as:

```plaintext
hello.lisp

```

and run:

```bash
sbcl --script hello.lisp

```

Output:

```plaintext
Hello, world!

```

A function looks like this:

```lisp
(defun square (x)
  (* x x))

(format t "~D~%" (square 12))

```

Output:

```plaintext
144

```

Or interactively, start SBCL:

```bash
$ sbcl

```

and use the REPL:

```lisp
* (+ 2 3)
5

* (defun square (x) (* x x))
SQUARE

* (square 12)
144

```

Nothing especially strange yet.

But Lisp gets interesting when you realize that **Lisp programs are represented using the same data structures Lisp programs manipulate**.

## Code that writes code

Here is a macro:

```lisp
(defmacro repeat (n &body body)
  `(loop repeat ,n
         do (progn ,@body)))

```

Now we can write:

```lisp
(repeat 3
  (format t "The machine dreams in parentheses.~%"))

```

Output:

```plaintext
The machine dreams in parentheses.
The machine dreams in parentheses.
The machine dreams in parentheses.

```

This looks like we added a new construct called `repeat` to the language.

In a sense, we did.

The macro receives Lisp source code as data and transforms it into another Lisp program before compilation.

We can see what it generates:

```lisp
(macroexpand-1
 '(repeat 3
    (format t "hello~%")))

```

Conceptually it becomes:

```lisp
(loop repeat 3
      do (progn
           (format t "hello~%")))

```

The strange-looking part is:

```lisp
`(loop repeat ,n
       do (progn ,@body))

```

The backtick is **quasiquote**.

Inside it:

```lisp
,n

```

inserts one value, while:

```lisp
,@body

```

splices an entire list of expressions into the generated program.

Lisp isn’t merely executing code here.

It is **constructing code, transforming it, and then compiling the result**.

## Creating a function at runtime

It gets stranger.

```lisp
(let ((operation '+))
  (let ((f
          (compile nil
                   `(lambda (x y)
                      (,operation x y)))))
    (funcall f 100 23)))

```

Result:

```plaintext
123

```

What happened?

First:

```lisp
(operation '+)

```

stores the symbol `+` as ordinary data.

Then this:

```lisp
`(lambda (x y)
   (,operation x y))

```

constructs the Lisp program:

```lisp
(lambda (x y)
  (+ x y))

```

Then:

```lisp
compile

```

asks SBCL to compile that newly constructed function.

Finally:

```lisp
(funcall f 100 23)

```

executes it.

So a running program just:

1. represented another program as data;
2. generated source code;
3. compiled that source code;
4. produced a native function;
5. called the function.

All at runtime.

## Ask SBCL what machine code it generated

SBCL also lets us look beneath Lisp and inspect the actual native machine code produced by the compiler.

```lisp
(defun mysterious-function (x)
  (+ (* x x) 42))

(compile 'mysterious-function)

(disassemble #'mysterious-function)

```

SBCL will print the native instructions generated for the function.

Instead of treating Lisp as some interpreted scripting language, SBCL can turn something like:

```lisp
(+ (* x x) 42)

```

into actual machine code for the host CPU.

This combination is one of the things that makes Common Lisp fascinating:

- interactive REPL;
- runtime compilation;
- native code;
- macros;
- introspection;
- code represented as data;
- programs capable of constructing other programs.

## The important distinction

Strictly speaking, the language here is **Common Lisp**.

SBCL is the implementation.

That is analogous to saying:

```plaintext
Language: Common Lisp
Implementation: SBCL

```

Other Common Lisp implementations exist, including:

- Clozure CL
- ECL
- ABCL
- LispWorks
- Allegro CL
- CMUCL

But on a modern Unix system, if I wanted to simply install Common Lisp and start programming, **SBCL would probably be my default choice**.

On Debian/Ubuntu:

```bash
sudo apt install sbcl

```

On macOS:

```bash
brew install sbcl

```

Then:

```bash
sbcl

```

and suddenly you’re sitting at a descendant of a programming tradition that goes back to **John McCarthy’s Lisp work in 1958**.

Almost seventy years later, the parentheses are still alive.
