Running Allegro Common Lisp From Emacs

Getting Started

A much more powerful alternative to running ACL from the Unix command
line is to run Allegro Common Lisp (ACL) within one window of an Emacs
screen. If you are not familiar with the rudiments of Emacs, you will
want to look over the Emacs handout for this course before proceeding
with the tutorial in this handout.

The advantages of running ACL from within Emacs are many. While the
interface between ACL and Emacs is quite sophisticated and
complicated, most of the complexity is hidden, and the sophistication
will help you with many common operations. For instance, you gain the
ability to type Lisp expressions into an editor buffer, using the full
power of the editor to modify and change them, and with a single
keystroke, have Emacs evaluate these expressions. In addition,
documentation on functions, arguments to functions, and source files
containing function definitions can all be called up with a single
keystroke.

To run ACL from within Emacs requires that you `tell' Emacs how to
connect to ACL. The means you will need to add some lines to your
.emacs file for initializing Emacs. The complete listing of
these commands follows. However, you need not retype all these
commands. They can be found in the file allegro-dot-emacs-additions,
but look exactly like:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; The Hooks for using Allegro Common Lisp from within Emacs
(setq load-path (cons "/usr/local/allegro/home/emacs/fi" load-path))
(load "fi-site-init")
; It appears loading fi leaves emacs default directory hosed. Thus,
; let's set it back to the current directory ;;; Customize the common
; lisp invocation command for emacs.
(setq default-directory (expand-file-name "."))
; The default buffer name is "*common-lisp*" but this can be changed
(setq fi:common-lisp-buffer-name "*common-lisp*")
; The directory should be where emacs was started
(setq fi:common-lisp-directory (expand-file-name "./"))
; The default buffer image name is "cl" but we use pb_clim2xm_composer
(setq fi:common-lisp-image-name "class-lisp")
; The image arguments can be modified, new arguments can be added
(setq fi:common-lisp-image-arguments nil)
; The host can also be specified
;(setq fi:common-lisp-host "faure")
(defun acl ()
"This function starts up Allegro Common Lisp with your defaults"
(interactive)
(fi:common-lisp fi:common-lisp-buffer-name
fi:common-lisp-directory
fi:common-lisp-image-name
fi:common-lisp-image-arguments)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

After modifying your .emacs file, you can start up Emacs and
then type ESC-x acl which will open a window and start up
ACL in that window.
In case you cannot think of something to say, take lisp for a spin by
typing the following:

(sqrt 12321)

Lisp will come back telling you that the square root of 12,321 is 111.
The tutorial below has more things to try.

Quick Tour of the Emacs to Lisp Interface

To get you started with the Emacs to Lisp interface, the following
tutorial should be helpful. While you will be defining very simple
Common Lisp functions in this tutorial, the point is not to explain
the Lisp. Lisp as a language will be covered in the lectures with
reference materials on reserve. The point is to get you a foot hold
into the practical side of using Lisp from within Emacs.
To begin, follow the instruction above for starting ACL within Emacs and
get to the point where you are looking at the prompt:

USER(1):

Real Basic Stuff

You are now talking with the Lisp `read-eval-print' loop. What
this means is that you type an expression into Lisp, it goes off
and thinks about it - evaluating the expression - and then returns
its answer. Thus, to evaluate the sum of the integers 1 and 2
enter:

USER(22): (+ 1 2)
3

The ( opens the expression, the symbol +
indicates you wish to evaluate the following arguments with the
function that performs addition, the arguments follow, and finally
the expression is closed off with a right parenthesis
). The response, 3, is printed on the following line.
So far pretty elementary... You can nest expressions in the following
fashion.

USER(23): (+ (+ 1 2) (+ 3 4))
10

Many Lisp functions also allow variable numbers of arguments. Thus, you
could accomplish the same addition with:

USER(24): (+ 1 2 3 4)
10

You can record values for later use by binding them to variables.
Thus, you can introduce the symbol foo and bind it to
the value returned from an expression.

USER(25): (setf foo (+ 1 2 3 4))
10
USER(26): foo
10

The first expression has bound the value 10 to the variable
foo. The second expression, consisting only of the symbol
name, when evaluated, returns the value of the symbol.

Making your own functions

You can add a function to the existing set of Common Lisp functions using
the special form defun. For the moment, do not worry about what
'special form' means, we'll get there in lecture.
Thus, to create a function to increment a value by 1, you type in
the following:

With this example, we touch on a subtle point. A function can be
instructed to print text using the format
function. In this case, the text appears in the obvious place, the
interaction window. What the function prints and what it returns
as its value when evaluated should not be confused. The Hello
World appearing when you evaluate the function is the
consequence of executing the format statement. The
NIL on the following line is the actual value returned
by the function. NIL is a particularly important value. It
has several interpretations which will only really make sense once
you are more familiar with the basics of lisp. Think of it now as
simply a null value.

The ACL debugger is a tremendously useful tool. However, our goal
for the moment is simply to let you get back to `top-level' and
forget about your typo. What you notice is that a [1]
has appeared to the left of the usual prompt. Simplifying
dreadfully, this means Lisp has caught your mistake, left a place
holder as to what you were attempting to do, and is now again
letting you evaluate expressions. The expressions can include
directives to the debugger. The most basic directive means
essentially 'get me out of here' and can be given by typing
:pop. For example:

[1] USER(54): :pop
USER(55):

You could alternatively type :help and Lisp would print out a
complete listing of commands you can enter.

Keystrokes to Learn More

One of the great advantages of using Lisp from within the Emacs interface
is the ability to call up the argument lists and function documentation on
any function. This includes functions defined in the basic language as well
as those defined by other people whose code you are using, and finally
documentation on your own functions. (Alas, this interface seems to
be unable to access the documentation strings for many of the basic
Lisp functions.)

Getting Function Documentation

For example, imagine you know about the function
hello-my-name-is, but you are not quite sure what it
does. You can call up its documentation string by simply starting
to type the function, i.e.

USER(35): (hello-my-name-is

Now, with the cursor placed to the right of the function name, type the
following keystrokes:

Esc-Sh-F

To clarify our conventions for identifying keystrokes, this means you
should depress the escape key, followed by the shift and F keys
together. (Optionally, on some Sparc keyboards there is a key next
to the space bar with a diamond on it. Anything that can be accomplished by
typing escape followed by other keys can be done with the diamond
depressing the diamond key while depressing the other keys.)

Emacs will now ask you in the small one line window at the bottom to
confirm your request; it will say:

Function documentation for symbol: (default hello-my-name-is)

Typically you want the default, and so by simply entering
Ret, Emacs will print the documentation string to either
this same display line, if it is small, or to a help window if it
is larger. So, in this case, you will see displayed:

Program to greet newcomers other than Bob

This is your first way of finding descriptions of what functions in Lisp
do.

One minor digression on the point of documentation strings, in a
major step backwards, Allegro Common Lisp has adopted the
convention of other Unix Common Lisp systems and saved disk and
memory space by removing documentation strings from the common
functions, which is too bad since systems 15 years ago running on
Lisp Machines with 8MB of memory routinely kept complete
documentation available with only a keystroke. When writing your
own Lisp code, it is very good practice to include documentation
strings.

Getting The Arguments to a Function

Another common frustration when writing code is not remembering the
arguments to a function.

The function expt is used to raise a number to a
power. This is a classic example of a function where one might
forget the order of the arguments. Hence, you can type the
following (leaving the cursor to the right of the last character)

USER(51): (expt

and now type

Esc-Sh-a

Emacs will ask you in the bottom window to confirm your request. Simply hit
Ret and it will display the following:

EXPT's arglist: (BASE POWER)

This tells you the function takes two arguments. The first is the base and
the second is the power to which you want it raised. Thus, to raise 8 to
the 3rd power, you would type:

USER(51): (expt 8 3)
512

These are the two most basic and I find commonly used control keys for
gaining information. There is one more mechanism which is independent of
the Emacs to Lisp interface but still incredibly useful, and that is the
apropos function

Apropos: Give Me Things with Names Containing a String

You remember there is some function you want to use, but you cannot
remember the exact name. However, you are pretty sure it contains the
string "hello". Do the following:

The function apropos looks for all things defined
which contain the indicated string in their names. The way you
restrict attention to those things in the user package is
with the second argument. I recommend doing this until you
understand more about packages: otherwise you'll see many things
which will make little sense to you.

Note that you are told what things it finds, along with whether they are
functions, and if so what arguments they take.

I Want to Write My Programs In Files

While using the Lisp interaction buffer of Emacs to write simple
expressions is fine; however, whenever you are starting to write a
real program, you will want to do so in a named file which you keep
around. There are some nice features of the Emacs to Lisp
interface to help you.

Let's begin by creating a file. You can do this easily in Emacs
using the keystrokes C-x C-f. Again, this is shorthand
for typing control x followed by control f.
Emacs will now ask you to enter the name of the file at the bottom
of the screen. For this tutorial you should type:

my-name-is.lisp

Be aware that Emacs may already give you a path to which what you type is
appended. If the path is to the directory where you want to put the file
(which it should be by default), this is helpful. However, if you don't
watch and it tries to create the file in some other directory, this can
lead to problems.

If a file of this name already exists, you will now be in a new buffer
looking at the contents. More likely, no such file existed beforehand, and
you are now looking at a new buffer which is empty.

For this tutorial, your file my-name-is.lisp should contain the
following:

Now you are ready to learn something about how to communicate between files
containing your Lisp code and the Common Lisp buffer.

Evaluating a Previously Entered Expression

In the *common-lisp* buffer you may want to make a minor
change to a previous line you entered and then evaluate it
again. This is made extremely simple for you by the emacs to lisp
interface. If you simply put the cursor at the end of any
expression in the buffer and hit return, emacs will submit this
expression to the Lisp interpreter. You can also use emacs to make
changes in the line before you hit return.

Evaluating/Compiling an Emacs Buffer

Go to the buffer containing your file. Type the following:

C-c C-b

You will see it display the message that it is compiling. If you have
entered everything correctly, it will quickly follow the compiling message
with the word done at the bottom of the screen.

Your function has become part of the Lisp environment and can be used like
other functions.

Evaluating/Compiling Part of a Buffer

If you go back to the file my-name-is you can compile just
the function definition by placing the cursor at the end of the
defun expression. This is after the final
) which closes off the function at the bottom of the
file. Now simply type:

C-c C-s

Try this by changing Bob to your own name and running the
function. In my case, I modify the function so it appears as follows:

Then I place the cursor at the end of the function and type
C-c C-s. The compiling message followed by the done
message appears at the bottom of the screen. Now if I call the
function in the Common Lisp buffer I get the following response:

USER(64): (my-name-is "Ross")
Go Away Ross
NIL
USER(65):

Automatically Loading Files Where Functions Reside

A more advanced, but very convenient feature of this interface is that with
one keystroke you can load the file in which a function is defined.
If you are just getting started, and feel you have learned enough, you need
not push on through this section.
To really see the benefit of this, you will want first to delete
the buffer in which you have the file in which you have defined the
function my-name-is. A reminder about Emacs, to do
this, you can simply type:

C-x k

If you are already in the buffer containing your file, this will be the
default and you need only hit return.
Now, if you type:

C-x C-b

Emacs will display a complete list of all the buffers as well as what files
are associated with those buffers which represent files. Note some
buffers, like the *common-lisp* buffer have no corresponding files.

A passing comment, one way to move between buffers is to move the
cursor into this display, select a line naming a particular buffer
and type f. This will bring up this buffer in the
window.

Now, to see how Emacs can track down where you source code lives, go to the
Common Lisp buffer and type out the name of the function

USER(66): (my-name-is

and without completing it and leaving the cursor at the right most point on
the line, type

C-c .

Emacs will ask you the following question at the bottom of the screen:

Lisp Locate source: (default my-name-is)

If you type return, then Emacs will find the
source file in which this function is defined, load it, and open it
up in a window. Initially, you may not find this capability
important, but as you begin to manage larger programs, it can be
very handy.