REPL Extensions in Standalone EXE
Clone this wiki locally
REPL extensions in standalone executables
Prebuilt standalone SBCL executables for Windows, available for download at the build status page, include a few modules from “SYS:CONTRIB;” collection. This list includes an extended REPL (SB-ACLREPL module).
When building standalone executable images, I add some features to SB-ACLREPL (this part of build process uses noticeable amount of code that is unpublished now).
SB-ACLREPL:ALIAS facility is used for their definition; the standard
:aliases command prints a list of them, with a brief description of each
Current command set provides a convenient way of bootstrapping Quicklisp and loading systems provided by its repository.
Bootstrapping happens automatically when a Quicklisp-related command is entered for the first time, unless quicklisp is already loaded by other means at that moment: initial quicklisp.lisp (loaded from a socket stream) brings in another parts and the repository metadata.
Arguments for this kind of commands are never evaluated. They should be
either symbols or string literals; non-qualified symbols that are used as
string designators are not interned to the current
*package* (internally, a
special temporal package is used to achieve this).
Load one or more systems.
Search system and release names in Quicklisp repository; list matching
systems (the facility itself is provided by
Update Quicklisp metadata. With no arguments, update all subscribed dists and also Quicklisp client.
Experimental: start SWANK server and SLIME client on local machine. This command is available since sbcl-22.214.171.124.mswinmt.919.
Multiple things happen here, even if we forget quicklisp
quicklisp-slime-helper are quickloaded;
then a registry is examined for Emacs installation (emacs_dir value under
SOFTWARE/GNU/Emacs key, in HKCU and HKLM; the value at HKLM is written by
EmacsW32 project’s install wizard). If Emacs installation root is found
during this step,
started with command-line options that should make it load SLIME (from the
quickloaded release) and connect to SBCL binary that received
If Emacs installation root is not found by reading the registry, an open
file dialog is displayed (“Where is your emacs?”), and the answer is used to
start SLIME. If
emacsclientw.exe is available in the same directory as
the selected executable (which is supposed to be
emacs.exe), this command will prefer it.
I’m going to make some customization of this command’s behavior possible, if it proves to be useful; even now, it is a good tool to have SLIME running as soon as possible, if all you have is a modern GNU Emacs and one of my SBCL executables.
Very Experimental: list Quicklisp systems that are known to be loaded by ASDF. Expect it to be broken or unreliable; for now, it’s the single command that works with ASDF directly; that would be bad enough, but it may also be affected by method definitions provided by particular systems.
Outer Parentheses May Be Omitted
I’ve reimplemented a facility from some older REPL (I don’t remember its name, only the idea): for ordinary S-expressions, a new postprocessing step was added. If a command line starts with a symbol that is FBOUND, but makes no sense as variable, the line is reinterpreted as if there were additional parentheses around (the precondition I use is probably stronger than expected; the purpose is to avoid any reinterpretation unless it’s obviously makes more sense than the original form).
Reinterpreted form is pretty-printed (with ;;; line prefix) before execution. Here is an example REPL session fragment:
CL-USER(9): list 1 2 3 ;;; => (LIST 1 2 3) (1 2 3) CL-USER(10):
No attempt at reinterpretation is made if the last S-expression on the first line is incomplete, with the intent to avoid confusion caused by reinterpretation of non-trivial inputs (e.g. something received from redirected standard input).
REPL Override Warning
There are some other variants of extended REPL, like the one provided by a (quicklispable) GBBopen project. Some users may prefer SB-ACLREPL with the extensions, even if they need some of GBBopen modules.
SB-INT:*REPL-READ-FORM-FUN* is modified but a prompt code is left
intact, a simple warning will be signalled before the next REPL prompt:
WARNING: REPL behavior was overridden to use #<FUNCTION EXTENDED-REPL-READ-FORM-FUN> for reading forms. Among other things, it may mean that our Quicklisp goodies, like :qload and :qapropos, won't be available any more. Invoke (RESTORE-ACLREPL) to get back the form reader provided by SB-ACLREPL.
As it says,
(COMMON-LISP-USER:RESTORE-ACLREPL) rolls back the changes;
after it’s invoked, the original SB-ACLREPL with extensions will be used for
all new listeners (including those created by default toplevel function of
the dumped image).
Image Startup Sequence
When a new image is dumped and restarted later, both Quicklisp and ASDF can
become confused upon restart: the first one keeps its repository location at
ql:*quicklisp-home*, and the second keeps user cache directory
asdf::*user-cache*. Before dumping standalone binaries, I
install the init-hook designed to do the right thing when possible.
- ASDF User cache location is reinitialized according to the current user
profile (side note: local application data directory is used for this
purpose, instead of e.g. top-level
%AppData%, to avoid cluttering roaming user profiles with cached FASLs).
- If Quicklisp was loaded automatically during extended command execution,
QL:*QUICKLISP-HOME*(which defaults to
%UserProfile%/quicklisp/) is adjusted for current user profile as well. If some other way of loading quicklisp was used, no adjustment happens.
Image information (describing the unofficial build, its version, preloaded
modules, and providing some relevant URLs) is printed by the original
executables in the absence of command-line arguments. It’s never printed by
non-original images (dumped with
(SB-EXT:SAVE-LISP-AND-DIE) by the user).