The MOP in CMUCL is based on PCL and works pretty much like AMOP describes.
There is however an oddity with it that has to do with ``wrapper'' classes,
the details of which I (dan) unfortunately can't remember (so, somebody please
edit this). Anyway, a reasonable fix is to work in a package that shadows
a bunch of symbols from PCL instead of picking up the default versions in COMMON-LISP :

Running Lisp programs from the shell prompt

Note that this works on Linux systems only (tested on Slackware 7.0 by the original poster). Depends on having a kernel compiled with the binfmt_misc module enabled, and root access to setup binfmt_misc. Any user can run the scripts.

Note that it'd be even better to use ${1+"$@"} instead
of $* in the shell script to pass through all the
parameters untouched.

Explanation:

$* first concatenates all parameters, separating
them with space (the first character of $IFS, in fact),
and after that, splits them again according to $IFS.
My suggestion does NOT do this. This matters when some parameters
contain whitespace, such as/some/program -name 'Hannah Schroeter'

-- Hannah Schr?ter hannah@schlund.de, 22 May 2001

Note that debian provides a wrapper ``cmucl-run'' with the cmucl package, which can be used with binfmt-support for binfmt_misc goodness.

CMUCL shell scripts

This is an alternative method to the linux-specific binfmt_misc method above, which should work on all Unix platforms. It consists of using a small trampoline program which invokes the CMUCL runtime with a rewritten argv. Your shell script looks something like

#!/usr/bin/cmucl-trampoline \
-quiet -batch -noinit
!#

(format t "~&Hello, world!~%")

You need to download the cmucl-trampoline program, and your image must contain a reader macro which treats #!..!# as comments (there is example lisp in the code).

Another way relies on your shell automatically interpreting executable files not marked with #! itself:

# A handy script to run Lisp as shellscripts. In the top of your
# file, put:
#
# #!/usr/bin/env runlisp
#
# and stick runlisp (this script) somewhere in your path. Then you
# can have regular-looking shellscripts that are written in Lisp.

# If you have another Lisp implementation and know what arguments to
# pass to it for this to work, feel free to add it and send me
# (erik@nittin.net) the patch.

CLX over ssh-forwarded displays

The standard CLX function OPEN-DISPLAY doesn't correctly extract the display number from the DISPLAY environment variable. This is a problem you might run into when using CLX on an ssh-forwarded X11 session. Indeed, ssh typically sets $DISPLAY to remotehost:10, and forwards port 6010 on the remote host to port 6000 (or whatever port the local X11 server is running on) on the local host. CLX will unsuccessfully try to connect to remotehost:0.

The solution is to use the CMUCL-specific function EXT:OPEN-CLX-DISPLAY instead of XLIB:OPEN-DISPLAY. This function will parse the DISPLAY environment variable to extract the display and screen numbers.

Note that the version of CLX distributed with CMUCL includes a number of extensions to the original code. It is able to extract X11 authorization cookies from the file mentioned by the XAUTHORITY environment variable (defaulting to ~/.Xauthority), and it includes hooks into CMUCL's SERVE-EVENT facility.

NB: Many people seem to find that this does not work for them, as the question of how to use CLX locally without turning off access control is a frequent question on c.l.lisp and the CMUCL mailing list.

SERVE-EVENT example

An example of CMUCL's SERVE-EVENT facility, that allows you to handle multiple concurrent network connections and file handles, without using multithreading. The program is a port forwarder, or redirector. It redirects TCP connections to another port on another machine. Get it from purl.org/net/emarsden/home/downloads/.

Adding commandline switches

Certain implementations such as CLISP have a -c commandline switch that allows you to invoke the file compiler from the shell. CMUCL's commandline switches are user-extensible, so you can emulate this behaviour with code such as the following, in your site-init.lisp or ~/.cmucl-init initialization files.

Now you can use the following to compile (and load) from the command
line:

lisp -compile-and-load demo.lisp demo2.lisp

If errors are encountered during processing, CMUCL is aborted, with a
return value of 1, otherwise it returns 0 (i.e. success). This can be combined with the -quiet flag (put it at the start of the
commandline) if wanted.

An alternative to this form of interaction with the file compiler is to load the files and compile them from a stream, so you don't have any FASL files hanging around on disk (thus avoiding problems with binary compatibility between different CMUCL releases), yet still benefit from compiled performance. You can do this with code such as:

Adapted from article 87g06vubxi.fsf@orion.bln.pmsf.de posted to comp.lang.lisp by Pierre Mai, on 2001-11-30.

"Advise" facilities

In CMUCL 18e and later, use fwrappers; the encapsulation mechanism described below is deprecated.

from the release notes for CMUCL 17f:

-- The encapsulation mechanism (similar to advise facilities) has been
revamped to work on SETF function names as well as symbols.
EXT:ENCAPSULATED-DEFINITION
Returns whatever definition is stored for name, regardless of whether
it is encapsulated. Unlike FDEFINITION, this does not strip off the
encapsulation. This is SETF'able.
EXT:ENCAPSULATE
Replaces the definition of name with a function that binds name's
arguments a variable named argument-list, binds name's definition to a
variable named basic-definition, and EVAL's body in that context. Type
is whatever you would like to associate with this encapsulation for
identification in case you need multiple encapsuations of the same
name.
EXT:UNENCAPSULATE
Removes name's most recent encapsulation of the specified type.
EXT:ENCAPSULATED-P
Returns t if name has an encapsulation of the given type, otherwise
nil.
EXT:*SETF-FDEFINITION-HOOK*
A list of functions invoked by (SETF FDEFINITION) before storing the
new value. Each hook function must take the function name and the
new-value.

~/.inputrc file (actually the
file where $INPUTRC points to). I added the line

TAB: complete

because rlwrap binds this key to menu-complete.

Note that recent readline
versions include an example program rlfe that does almost the same
thing as rlwrap. I think rlwrap is nicer, though.
Update: I've slightly enhanced this hint (including a way to create better completions files) and put it here.

For those of you on Debian, cle that does pretty much the same thing
(but no tab-completion) is packaged on testing.