SLIME and Quicklisp not playing nice with each other - emacs

I'm using Emacs as my Common Lisp (SBCL, to be exact) editor, with SLIME. I set up Quicklisp as per the instructions here, and checked if it worked outside of SLIME, and everything was fine - I could grab and download code, include it, everything.
Now, I was trying to use the Compile/Load File command in Emacs for a source file with the following at the top:
(ql:quickload "priority-queue")
(defpackage :tournament
(:use :cl :priority-queue))
(in-package :tournament)
Now, once again, not in SLIME, this worked fine. However, in SLIME, I get an error of the following form:
The name "PRIORITY-QUEUE" does not designate any package.
[Condition of type SB-KERNEL:SIMPLE-PACKAGE-ERROR]
Plus a backtrace, of course. Am I missing something in particular? I installed slime using package-install from Emacs, and I have the following code in my .emacs file to set it up:
(setq inferior-lisp-program "/usr/local/bin/sbcl")
(require 'slime)
(slime-setup)

This is happening because of the separate times of compilation and loading.
When compiling, plain function calls (like ql:quickload) are not evaluated. When the compiler tries to process the defpackage form (which is not a plain function call, but a macro that has side-effects at compile-time), the function that loads "priority-queue" has not been called and the package is not available.
You won't see this if you load the file instead of compiling and loading, because load evaluates each form as it loads.
There are a few options available. The simplest is to wrap your call to ql:quickload in eval-when, e.g.
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload "priority-queue"))
I prefer to define a system for my projects, however small, so I would make a tournament.asd file that looks like this:
(asdf:defsystem #:tournament
:depends-on (#:priority-queue)
:serial t
:components ((:file "tournament.lisp")))
I'd put that in ~/quicklisp/local-projects/tournament/ (along with tournament.lisp) and use (ql:quickload "tournament") in the repl to get started and load it.
I use that latter setup so often that I wrote a Lisp program to do it for me called quickproject.

Related

Why does Lisp code execute if entered line by line in the REPL but not if compiled in the buffer?

I am a noob Lisper and am attempting Adam Tornhill's Lisp for the Web tutorial using Portacle Emacs.
I would very much appreciate an explanation of why the set-up code below will run happily and change the REPL cursor to RETRO-GAMES> if entered line by line in the REPL but does not seem to work if compiled in the buffer. (The first time it compiles it often throws an error saying it can't find the quickload packages; the REPL cursor never changes.)
If anyone can shed light on what this implies for compiled programs, it would be great. I'm struggling to understand the value of programming directly into a REPL rather than a saved file. If there are any noob-level resources on what a fully compiled program "looks like" in terms of whether it includes the type of loady code below, a link would make my day. Thank you.
(load "C:/Users/USER/portacle/all/quicklisp/quicklisp/setup.lisp")
(ql:quickload :cl-who)
(ql:quickload :hunchentoot)
(ql:quickload :parenscript)
(defpackage :retro-games
(:use :cl :cl-who :hunchentoot :parenscript))
(in-package :retro-games)
(defclass game ()
((name :initarg :name)
(votes :initform 0)))
To see why this code is a problem for compilation, consider what the compiler must do when compiling a file containing it, in a 'cold' Lisp image, where 'cold' here specifically means 'without Quicklisp loaded'. To see this, divide it into chunks. For the sake of argument we'll imagine that the way the file compiler works is to read a form from the file, compile it, and write it out. It does have to work in a way which is equivalent to this for our purposes so that's OK here.
First chunk
(load "C:/Users/USER/portacle/all/quicklisp/quicklisp/setup.lisp")
load is a normal function and the call to it occurs at top level in the file: what the compiler will do is to compile code so that, when the file is loaded this load is called. The compiler will not itself execute load, and so Quicklisp will not be loaded at compile time.
Second chunk
(ql:quickload :cl-who)
(ql:quickload :hunchentoot)
(ql:quickload :parenscript)
This code has two problems. In a cold lisp the QL package does not exist, because the previous load was not executed at compile-time, so the reader will raise an exception when reading these forms. Compilation will stop here.
If the Lisp is not cold and in particular if the QL package does exist (so, if the Lisp image which is doing the compilation does have Quicklisp loaded into it) then the compiler will simply write code which causes these three ql:quickload calls to take place at load-time, and will not load these three QL systems now.
In a cold lisp you will not get beyond this step. In a Lisp with Quicklisp loaded at compile time you will.
Third chunk
(defpackage :retro-games
(:use :cl :cl-who :hunchentoot :parenscript))
This chunk will only be reached in a Lisp where Quicklisp is loaded at compile time. This is a package definition, and it has effect at compile time, as it must do. But, at compile time, the calls in the second chunk have not yet taken place: this package definition refers to packages which do not exist. So this is a compile-time error and compilation will stop here.
If the Lisp doing the compilation not only has Quicklisp loadad but also has the three QL systems loaded, this will succeed.
Fourth chunk
(in-package :retro-games)
This will only be reached in a lisp which, at compile time, has both Quicklisp and the three QL systems loaded into it. In that case it tells the compiler that the following forms are to be read in the retro-games package. Otherwise it is never reached.
Fifth chunk
(defclass game ()
((name :initarg :name)
(votes :initform 0)))
In the unlikely event the compiler gets this far, this defines a class called retro-games::game.
What the problem is
The problem is that the compiler is, well, a compiler: what it does is compile code for later execution. But the later parts of your source depend on the earlier parts of your source having been loaded.
There are two ways to deal with this.
If you are only writing a very small amount of code, then you can tell the compiler that some things must happen at compile time as well as at load time. The way you do this is by eval-when, and the particular incantation you want is something like this, for chunks one and two:
(eval-when (:compile-toplevel :load-toplevel :execute)
(load "C:/Users/USER/portacle/all/quicklisp/quicklisp/setup.lisp"))
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload :cl-who)
(ql:quickload :hunchentoot)
(ql:quickload :parenscript))
Note you must have two separate incantations of eval-when because the QL package needs to be brought into being by the first so that the second can be read.
The semantics of eval-when are mildly hairy, but this incantation will do what you want: it will tell the compiler to load these things and make sure that they are also run at load time.
The second way of dealing with this, which is appropriate for larger systems, is to have one or more files which build the compile-time environment for later files, and which are compiled and loaded before the later files, under the control of something like ASDF. In this case you typically want some minimal bootstrap file, which perhaps simply needs to make sure that Quicklisp is loaded and then ask Quicklisp (and hence ASDF) to compile and load everything else, with dependency management looked after by those tools, so there would be no ql:quickloads at all. How to set up something like this is beyond this answer however!

Common Lisp: How to get (in-package ...) to work from within Emacs Slime

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.
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.
A little hard to find, but there is slime-repl-set-package:
(defun slime-connected-hook-switch-to-stumpwm-package ()
(slime-repl-set-package "STUMPWM"))
(add-hook #'slime-editing-mode-hook
#'slime-connected-hook-switch-to-stumpwm-package)

Call function in another lisp file

I have to write a game in Lisp. In order to make it clear, I wanted to split the code in different .lisp files.
How can I call a function out of a function in the other file?
E.g. file1.lisp has a function called function1 and file2.lisp has a function called function2.
How can I call function2 out of function1?
Thanks!
Just so you know, there are a variety of different Lisp systems. I'll post the answer for Common Lisp.
The naive way is to use (load "filename.lisp"), but that doesn't really work very well after a while. Therefore...
Common Lisp has a library called "ASDF", which handles packaging and file management. There's a bit of setup to ASDF.
Create directory where ASDF looks for files.
Add this information to my Lisp system's init file.
I use this in my .sbclrc file (assuming that I created a .asdf file in ~) :
(pushnew "~/.asdf/" asdf:*central-registry* :test #'equal)
I usually use a previously built ASDF file and then modify it.
Here's a sample ASDF file's contents:
(asdf:defsystem #:cl-linq
:depends-on ( #:alexandria #:anaphora)
:components ((:file "cl-linq"))
:name "cl-linq"
:version "0.1"
:maintainer "Paul Nathan"
:author "Paul Nathan"
:licence "LLGPL"
:description "CL LINQ style interface with strains of SQL"
:long-description
"DSL for managing and querying datasets in a SQL/LINQ style
syntax. cl-linq provides a simple and usable set of primitives to
make data examination straightforward. ")
I put this code in a file cl-linq.asd next to my source code (cl-linq.lisp from the component "cl-linq" in the defsystem) and then symlink the cl-linq.asd file to my ~/.asdf/ directory.
Within my cl-linq.lisp file I include this:
(defpackage :cl-linq
(:use
:common-lisp
:anaphora)
(:export
#:query
#:cl-linq-select))
(in-package :cl-linq)
So for your case, I would have 2 components; each with their own defpackage form, exporting the functions out that the other package needed.
For the examples, I've taken the code from CL-LINQ, a project of mine. You are quite free to use it as a template.
This is for Emacs Lisp (aka elisp)
Create a file at this location: ~/.emacs.d/init.el
Create a file at this location: ~/.emacs.d/file1.el
Create a file at this location: ~/.emacs.d/file2.el
Now, open up ~/.emacs.d/init.el and write (and then save):
(load "~/.emacs.d/file1.el")
(load "~/.emacs.d/file2.el")
(defun run-both-functions ()
(interactive)
(switch-to-buffer "*Messages*")
(first-function)
(sit-for 2)
(second-function))
Now, open up ~/.emacs.d/file1.el and write (and then save):
(defun first-function ()
(message "My name is Fred."))
Now, open up ~/.emacs.d/file2.el and write (and then save):
(defun second-function ()
(message "My name is George."))
Now, restart Emacs and type: M-x run-both-functions RET
Any functions that you put into any of the three (3) files mentioned above will be accessible to other functions. You will note that run-both-functions includes an (interactive) statement, which means that the user can call the function with M-x or a keyboard shortcut.
If you use the function load it can be useful to not specify the file type.
Loading files: fasl or source
Instead of (load "foo.lisp") one can call (load "foo"). Typically Common Lisp provides the feature of compiling Lisp files to fasl (fast load) files. Those are usually pre-compiled byte code or native code. Typically the Common Lisp implementation will load the compiled code if a file exists for it. This saves time (because compiled code usually can be loaded much faster than Lisp source code) and the code usually is faster (because a file compiler has compiled it).
Often one uses a function to load the compiled file if it is newer, or first compile the source file to a new compiled file.
Loading a file, based on the current file being loaded
In (load "foo") the file foo is not a complete filename. For example we don't know the directory where it is loaded from. This depends on things like the value of *default-pathname-defaults* or in some implementations on a current directory (typical for Unix systems). It may be useful to load the file based on the file we are currently loading - if loading one file triggers more files to be loaded. For this Common Lisp has the variables *load-pathname* and *load-truename* (which is the real filename as used with the filesystem).
To load a file foo in the same directory as the currently loaded file call:
(load (merge-pathnames "foo" *load-pathname*))
To load a file foo in a subdirectory bar of the same directory as the currently loaded file call:
(load (merge-pathnames "bar/foo" *load-pathname*))
With Common Lisp I done it like this:
In file1.lisp I define a function sayHello and export that function under the package name helloLisp
(defpackage :helloLisp
(:use :common-lisp)
(:export #:sayHello))
(in-package :helloLisp)
(defun sayHello () (print "Hello!"))
In the file file2.lisp I require this file like that:
(require "helloLisp" "./file1.lisp")
(helloLisp:sayHello)
Tested with SBCL 1.4.11

Controlling verbosity of byte-compilation (CL library)

When byte-compiling several eLisp files in a batch the output from the compiler is cluttered with Warning: function `position' from cl package called at runtime warnings. I understand, although don't agree that much with the policy on cl package. But this makes spotting other, more useful warnings more difficult. So, while there's no real way to avoid the warning, is there a way to selectively shut off all warnings of a certain pattern?
EDIT: (attached an example)
create file called doodles.el
(require 'cl)
(eval-when-compile (require 'cl))
(dotimes (i 1)
(position ?\x "x"))
M-x byte-compile-file RET doodles.el
Switch to *Compile-Log* buffer:
doodles.el:1:1:Warning: cl package required at runtime
this is what you get.
You can control byte-compiler warnings with a Local variables block that sets the byte-compile-warnings variable. To turn off the CL-at-runtime warning, place this near the end of your module:
;; Local Variables:
;; byte-compile-warnings: (not cl-functions)
;; End:
The warning function position from cl package called at runtime is not there because of the policy on CL (well, it does have something to do with it, admittedly) but is pointing out an actual real problem: you use position in a file which does not (require 'cl). The file probably does (eval-when-compile (require 'cl)) which means CL is available during compilation (a.g. to expand CL macros), but will not be loaded at run time.
Often this does not result in a bug, because some other file somewhere does (require 'cl) for you, but that's just you being lucky.

How to make and use library with lisp (clisp)?

In C/C++, I can make a library, and make it static one or dll using #include "" in source code, and -labc when linking.
How do I have the same feature in lisp?
As an example of util.lisp in directory A. I define a library function hello.
(defpackage "UTIL"
(:use "COMMON-LISP")
(:nicknames "UT")
(:export "HELLO"))
(in-package util)
(defun hello ()
(format t "hello, world"))
And try to use this library function from main function.
(defun main ()
(ut:hello))
(main)
I tried
clisp main.lisp A/util.lisp
But, I got the following message
*** - READ from #: there is no package with name "UT"
What's the equivalent of #include "" to use the library?
What's the equivalent of -lutil to load the library? What's the command line for clisp/sbcl to use the library?
And for defpackage, Is this equivalent to namespace?
ADDED
I just had to load the library.
(load "./A/util.lisp")
(defun main ()
(ut:hello))
(main)
And run 'clisp main.lisp' works fine.
What you are looking for are called systems. Common Lisp's defpackage has nothing to do with this, and yes, it's about namespaces. Have a look at the HyperSpec, or the idiot's guide (see Xach's comment below) to read more about it.
You can restrict yourself to merely loading files, but usually, a system definition facility is used; mostly ASDF nowadays. A minimal example:
(defsystem my-system
:name "my-system"
:version "0.0.1"
:author "myself"
:license "LLGPL"
:description "it's a system."
:serial t
:components ((:file "packages")
(:file "stuff")
(:file "more_stuff")))
Where packages.lisp would contain the package definition, stuff and more_stuff are the lisp or fasl files to be loaded. This system definition (usually named filename.asd) must be symlinked to (or located in) a directory contained in asdf:*central-registry* for ASDF to find your system. Then, you can load the system thusly:
(asdf:oos 'asdf:load-op 'my-system)
An alternative to this has been added in more recent versions of ASDF:
(asdf:load-system 'my-system)
Or, when using slime, by pressing ,l my-system RET.
You have to load util.lisp before main.lisp:
> (load "util.lisp")
> (load "main.lisp")
> (main)
hello, world
NIL
Practical Common Lisp has a good introduction to defining and using packages.
Common Lisp is an image base language, although usually to a lesser extent than Smalltalk. This means that you use a library by loading it into the image, using LOAD (if used explicitly the often in form (load (compile-file "your-file-here"))), or usually with a system definition facility like ASDF. The loaded code is then available for all code compiled/loaded in the future.
Packages are indeed namespaces. They deal with mapping strings to symbols only, they are not connected directly to files or functions or anything else. You received a package error because you attempted to load a file using a package before a file defining it.