Common Lisp: How to get (in-package ...) to work from within Emacs Slime
ccl, common-lisp, emacs, eval-when, slime
Solution
When you compile the file as a whole, it is first read as a whole. At that time, none of it has yet been evaluated, so the package `QT` is not defined yet.
You can either use `eval-when` to evaluate something at an earlier time, or use a system definition facility (ASDF is predominant nowadays) to load your system in the right order.
`Eval-when`:
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload '#:qt))
(in-package #:qt)
Note that you usually should not muck around in library packages but define your own, fresh package to hold your code:
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload '#:qt))
(defpackage #:qt-example
(:use #:qt))
(in-package #:qt-example)
;; your code here
(In case you are wondering, `defpackage`, `defun`, `defclass` etc. are specially designed macros that expand to a form inside such an `eval-when`.)
This is sometimes OK for little one-off scripts. For systems of any noteworthy size, especially as soon as they have more than one source file, use ASDF:
;;;; qt-example.asd
(in-package #:cl-user)
(asdf:defsystem #:qt-experiments
:description "Some experiments with QT."
:serial t
:components ((:file "package")
(:file "qt-example"))
:depends-on (#:qt))
;;;; package.lisp
(defpackage #:qt-example
(:use #:qt))
;;;; qt-example.lisp
(in-package #:qt-example)
ASDF comes with most open-source Common Lisp implementations. You might need to set up the ASDF registry. I like to have one or two base directories for all my local projects, so that I can just put the following into `~/.config/common-lisp/source-registry.conf`:
(:source-registry
(:tree (:home "devel"))
(:tree (:home "src"))
:inherit-configuration)
Then ASDF finds all systems defined below those directories. In SLIME, you can just use `,load-system` or `,open-system` from the REPL with the system name to load it, resp. open all files in it, optionally loading it.
When compiling a single toplevel form (using `C-c C-c`) from a file, SLIME looks backward from there for an `in-package` form to find out what package it should assume. Conventionally, you should only have a single `in-package` form per file, at its top.
A commonly useful shortcut is `C-c ~` in Lisp source files, which switches the REPL to the directory of the file and the effective package at point.
Problem
64-bit Windows 7 Clozure Common Lisp Version 1.9 WindowsX8632 Emacs 24.3.1 Slime changelog date 2014-06-17 I have an example .lisp file which starts out as follows: ``` (ql:quickload 'qt) (in-package "QT") ``` The rest of the program shows a dialog box. When I run this from the command line, `wx86cl -load helloqt.lisp` it seems to work fine. When I run this from Emacs Slime (`C-x C-k`) it says there is no package "QT". However if I first evaluate the first line individually (`C-x C-e`) then I can compile the whole thing and it works, modulo the normal issues of trying to run a QT thread from within Slime on Windows. How do I make it so I can compile/run the file from emacs without having to manually evaluate the first line first? Also, why doesn't `(in-package ...)` change the current package in the Slime session? I have to change it manually if I want to interact with the package contents.