--- layout: ../Site.layout.js --- # Steel bank common lisp, slime and save-lisp-and-die and not being ahistorical A point of confusion about lisp useage is this: In the most popular lisp compiler, [`sbcl`](https://sbcl.org), [saving and quitting are done in one action](https://sbcl.org/manual/index.html#Function-sb_002dext-save_002dlisp_002dand_002ddie): This produces a `.core` file, and you pick up again by loading the core which is literally the place you issued `sb-ext:save-lisp-and-die`. This is consciously similar to cold booting into your lispmachine universe (memory band). You don't have to recreate the state you left off, because that state itself was literally what you saved. Now the problem is that we almost always use lisp with slime, or something like it. Slime in emacs, lem or vim provides stuff like autocompletion, displaying where-you-are in a function's argument list that you are currently writing, an interface into lisp's debugging protocol and so forth. The problem is that the default way to use slime starts a background thread in your lisp image serving the swank wire protocol server that slime talks to your running lisp images over. But `sb-ext:save-lisp-and-die` doesn't know how to save an image running multiple threads (which is the default, with slime)! ## A simple way / example I am assuming you read my [starting-out-with-lisp article](/fundamental/installing-lisp-etc) and have [eev mode](https://anggtwu.net/#eev) in emacs! ### Eepitch-shell. `• (eepitch-shell)` Remembering that tapping F8 on a red star line in emacs evals some emacs lisp ### Explicitly sbcl in that shell and otherwise sends the line to your eepitch target buffer. `cd` `sbcl` ### Explicitly start the swank server in that sbcl `(merge-pathnames #P"~/.emacs.d/slime/"` ` #P"start-swank.lisp")` `(load *)` remembering that `*` means 'the last first value'. ``` * (merge-pathnames #P"~/.emacs.d/slime/" #P"start-swank.lisp") #P"~/.emacs.d/slime/start-swank.lisp" * (load *) WARNING: redefining EMACS-INSPECT (#) in DEFMETHOD ;; Swank started at port: 4005. T * ``` So, we have a background thread serving swank for our slime to `slime-connect` to. ### `slime-connect` to that `swank` server `• (slime-connect "localhost" 4005)` ``` ; SLIME 2.29.1 CL-USER> ``` Hacks and glory await! This is where we basically always use lisp from. It's got everything (and it has always had everything). [Here is slime's documentation about slime.](https://slime.common-lisp.dev/doc/html/) ### Do something in there `• (setq eepitch-buffer-name "*slime-repl sbcl*")` `(let ((count 0)) (lambda () (incf count)))` `(funcall *)` `(defparameter *counter* **)` `(funcall *counter*)` ### Let's disconnect. `• (slime-disconnect)` Let's go back to the shell sbcl is running in and save. `slime-disconnect`'s default already stopped the server, whose threads get cleaned up by default. `• (eepitch-shell)` `(sb-ext:save-lisp-and-die #p"foo.core")` ### Let's reconnect `sbcl --core foo.core` `(merge-pathnames #P"~/.emacs.d/slime/"` ` #P"start-swank.lisp")` `(load *)` `• (slime-connect "localhost" 4005)` ``` CL-USER> (funcall *counter*) 3 ``` and we're back! # Conclusion We saw that we can use the most popular lisp compiler, `sbcl` with `slime` in emacs with its `sb-ext:save-lisp-and-die` to save a core - literally our current image - and then load the core with `sbcl --core foo.core` where we saw our closure that we made in the lisp image still had the state we left it in. It is ahistorical to *not have* a persisted memory band universe between sessions on the lisp machines for example. It's not good enough to hope that in modern times, humans got really good at juggling text serialisations by hand - we are actually still bad at that. We still want and benefit from these futuristic features. # Fin. [Talk on the Mastodon as always please](https://gamerplus.org/@screwlisp/114905364606651576) I think some people do either end up not using `slime`, or not using sbcl's `ext:save-lisp-and-die` to save and resume their `universe` lisp image core when they are using `slime`. When you should.